Как найти среднее время между определенными событиями, которые входят в одну пользовательскую сессию?
Пожалуйста, помогите найти среднее время между определенными событиями входящих в одну сессию.
Например, есть датафрейм:
data = {
'id': [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5],
'event': ['login', 'news', 'comment', 'login', 'news', 'advt', 'login', 'like', 'comment', 'login', 'news', 'comment', 'login'],
'data': ['2023-03-15 10:00:00', '2023-03-15 10:05:00', '2023-03-15 10:10:00', '2023-03-15 10:15:00',
'2023-03-16 11:00:01', '2023-03-16 11:05:06', '2023-03-16 11:10:10',
'2023-03-17 12:00:02', '2023-03-17 12:05:00', '2023-03-17 12:10:30',
'2023-03-18 13:00:05', '2023-03-18 13:05:11', '2023-03-18 13:10:00', '2023-03-18 13:10:00']}
id - это id сессии. Как можно у каждой id сессии найти среднее время между login и между событием news или advt? Последовательность шагов строгая, первый шаг login второй выбранные события. Иногда в сессиях проскакивает что login был позже. Так же как можно код оптимизировать, чтобы он по возможности более оперативно обрабатывал большие датафреймы?
Ответы (2 шт):
Автор решения: CrazyElf
→ Ссылка
Ну я вам покажу примерный ход действий, дальше сами приспособите к своим задачам:
import pandas as pd
data = {
'id': [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5],
'event': ['login', 'news', 'comment', 'login', 'news', 'advt', 'login', 'like', 'comment', 'login', 'news', 'comment', 'login'],
'data': ['2023-03-15 10:00:00', '2023-03-15 10:05:00', '2023-03-15 10:10:00', '2023-03-15 10:15:00',
'2023-03-16 11:00:01', '2023-03-16 11:05:06', '2023-03-16 11:10:10',
'2023-03-17 12:00:02', '2023-03-17 12:05:00', '2023-03-17 12:10:30',
'2023-03-18 13:00:05', '2023-03-18 13:05:11', '2023-03-18 13:10:00']} #, '2023-03-18 13:10:00']}
df = pd.DataFrame(data)
# на всякий случай сортируем
df = df.sort_values(['id', 'data'])
df['data'] = pd.to_datetime(df['data'])
# отбираем только интересующие нас события
df1 = df[df.event.isin(['login','news'])].copy()
# формируем парные события и разницу между ними
df2 = df1.shift()
df1['evev'] = df2.event + '-' + df1.event
df1['diff'] = df1.data - df2.data
# выводим среднюю разницу по интересующей нас паре событий
print(df1[df1['evev'] == 'login-news']['diff'].mean())
Вывод:
0 days 16:33:12
Автор решения: Алексей Р
→ Ссылка
Примечания в коде
data = {
'id': [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5],
'event': ['login', 'news', 'comment', 'login', 'news', 'advt', 'login', 'like', 'comment', 'login', 'news', 'comment', 'login'],
'data': ['2023-03-15 10:00:00', '2023-03-15 10:05:00', '2023-03-15 10:10:00', '2023-03-15 10:15:00',
'2023-03-16 11:00:01', '2023-03-16 11:05:06', '2023-03-16 11:10:10',
'2023-03-17 12:00:02', '2023-03-17 12:05:00', '2023-03-17 12:10:30',
'2023-03-18 13:00:05', '2023-03-18 13:05:11', '2023-03-18 13:10:00']}
df = pd.DataFrame(data).astype({'data': 'datetime64[ns]'}) # создаем фрейм и преобразуем столбец `data` в тип даты/времени
logint = df[df['event'].eq('login')].groupby('id').last()['data'] # находим дату последнего (если их несколько) логинов для каждого ид
df = df.merge(logint, left_on='id', right_index=True, suffixes=('_event', '_login')) # проставляем во все строки фрейма моменты ранее найденных логинов для каждого ид
df = df[df['event'].isin(['news', 'advt'])] # фильтруем фрейм, оставляя только нужные события
df['delta'] = df['data_event'].sub(df['data_login']) # вычитаем из моментов событий моменты логинов
avg = df.groupby('id')['delta'].mean() # группируем фрейм по ид, находя по каждой группе среднее время. Если нужно в секундах, дописываем в конце .dt.total_seconds(), если в часах - еще .div(3600)
print(avg)
id
1 0 days 00:05:00
2 1 days 00:47:33.500000
4 1 days 00:49:35
Name: delta, dtype: timedelta64[ns]