У меня есть большой фреймворк данных, содержащий журналы пользователей на веб-сайте, и мне нужно найти продолжительность каждого посещения для каждого пользователя.Уменьшить время выполнения кода pandas
У меня есть 3,5 миллиона строк и 450 тысяч одиноких пользователей.
это мой код:
temp=df["server.REMOTE_ADDR"]# main df with timestamps and ip adresses
user_db = df["server.REMOTE_ADDR"]# df with all IP adresses
user_db = user_db.drop_duplicates() # drop duplicate IP
time_thresh = 15*60 # if user inactive for 15 minutes, it's a new visit
temp_moyen=[] # array for mean times
temp_min=[] # array for minimal time
temp_max=[] # array for max time
nb_visites=[] # array for number of visit
for k,user in enumerate(user_db.values): # for each user
print("User {}/{}").format(k+1,len(user_db.values))
t0=[] # time of beginning of visit
tf=[] # time of end of visit
times_db = df[temp == user]["server.date"].values # retrieve all timestamps for current user
times_db = [dateutil.parser.parse(times) for times in times_db] # parse to datetime
i=1
last_t = times_db[0]
delta = 0
while i<len(times_db): # while there is still a timestamp in the list
t0.append(times_db[i-1]) # begin the first visit
delta=0
while (delta < time_thresh and i<len(times_db)): # while not inactive for 15 minutes
delta = (times_db[i]-last_t).total_seconds()
last_t = times_db[i]
i+=1
if i!=len(times_db): #if not last run
tf.append(times_db[i-2])
else: # if no more timestamp, record the last one as end of last visit
tf.append(times_db[-1])
if len(times_db)<=1: # if only one timestamp, tf = t0
tf.append(times_db[-1])
diff=[(final-first).total_seconds() for first,final in zip(t0,tf)] # evaluate diff between each t0 and tf
temp_moyen.append(np.mean(diff)) # add to the lists
temp_min.append(np.min(diff))
temp_max.append(np.max(diff))
nb_visites.append(len(diff))
user_db=user_db.to_frame() # convert to dataframe
user_db["temp_moyen"]=temp_moyen # add columns for each information (mean,min,max,number of visits)
user_db["temp_min"]=temp_min
user_db["temp_max"]=temp_max
user_db["nb_visites"]=nb_visites
Этот код работает, но очень медленно: 200 пользователей/мин на моем компьютере. Что можно посмотреть:
определить узкое полость?
ускорить его?
EDIT: В соответствии с просьбой, мои данные выглядят следующим образом: пар каждый пользователь, у меня есть список временных меток: [100, 101, 104, 106, 109, 200, 209, 211, 213]
Мне нужно найти, сколько посещений один пользователь сделал, например, в этот случай, это будет представлять два посещения, 100-109 и 200-213. Первый визит продолжился 9, второй - 13, поэтому я могу иметь среднее, мин и максимальное количество посещений.
EDIT 2: Узкие здесь (277ms из 300мса на петлю):
times_db = df[temp == user]["server.date"].values # retrieve all timestamps for current user
Я положил его в списке понимания, прежде чем цикл, но он по-прежнему медленно:
times_db_all = [df[temp == user]["server.date"].values for user in user_db.values]
%timeit times_db_all = [df_temp[temp == user]["server.date"].values for user in user_db.values[0:3]]
1 loops, best of 3: 848 ms per loop #848ms for 3 users !!
мой дб выглядит следующим образом:
user_ip | server.date
1.1.1.1 datetime.datetime(2017, 1, 3, 0, 0, 3, tzinfo=tzutc()),
1.1.1.1 datetime.datetime(2017, 1, 4, 1, 7, 30, tzinfo=tzutc()),
3.3.3.3 datetime.datetime(2017, 1, 4, 5, 58, 52, tzinfo=tzutc()),
1.1.1.1 datetime.datetime(2017, 1, 10, 16, 22, 56, tzinfo=tzutc())
4.4.4.4 datetime.datetime(2017, 1, 10, 16, 23, 01, tzinfo=tzutc())
....
Первый вопрос, очевидно, необходимо ответить первым, для этого вы можете попробовать профилировать https://docs.python.org/2/library/profile.html. Это определит, какие процедуры занимают больше всего времени, как часто их вызывают и т. Д. И упреждающий ответ на второй вопрос заключается в том, что циклы обычно медленнее векторной операции. – KeithWM
Я согласен с вашей точкой в операции с вектором, я просто не вижу, как применить его в моем случае. Я попробую профилировать – CoMartel
Лучше было бы предоставить примерные данные, объясняющие, что вы пытаетесь сделать, и то, что вы ожидаете от результата. – piRSquared