#python #pandas
#python #pandas
Вопрос:
Представьте, что у меня есть фрейм данных с пользовательскими событиями
--------- ------------------ ---------------------
| user_id | event_name | timestamp |
--------- ------------------ ---------------------
| 1 | HomeAppear | 2020-12-13 06:38:14 |
--------- ------------------ ---------------------
| 1 | TariffsAppear | 2020-12-13 06:40:13 |
--------- ------------------ ---------------------
| 1 | CheckoutPayClick | 2020-12-13 06:50:12 |
--------- ------------------ ---------------------
| 2 | HomeAppear | 2020-12-13 11:38:33 |
--------- ------------------ ---------------------
| 2 | TariffsAppear | 2020-12-13 11:39:18 |
--------- ------------------ ---------------------
Для каждого пользователя после его последнего (по метке времени) события я хочу добавить новую строку с событием ‘End’ с той же меткой времени, что и в предыдущем событии:
--------- ------------------ ---------------------
| 1 | End | 2020-12-13 06:50:12 |
--------- ------------------ ---------------------
Я понятия не имею, как это сделать. В SQL я бы сделал это с помощью LAG() или LEAD(). Но как насчет pandas?
Ответ №1:
Используйте DataFrame.drop_duplicates
для последней строки User_id
, измените event_name
на End
и добавьте к оригиналу concat
с помощью индекса сортировки (добавлена безопасная сортировка mergesort
):
#if necessary sorting
df = df.sort_values(['user_id', 'timestamp'], ignore_index=True)
df2 = df.drop_duplicates('user_id', keep='last').assign(event_name = 'End')
df = pd.concat([df, df2]).sort_index(kind='mergesort').reset_index(drop=True)
print (df)
user_id event_name timestamp
0 1 HomeAppear 2020-12-13 06:38:14
1 1 TariffsAppear 2020-12-13 06:40:13
2 1 CheckoutPayClick 2020-12-13 06:50:12
3 1 End 2020-12-13 06:50:12
4 2 HomeAppear 2020-12-13 11:38:33
5 2 TariffsAppear 2020-12-13 11:39:18
6 2 End 2020-12-13 11:39:18
Комментарии:
1. Выглядит великолепно! Но как pandas будет рассматривать строку как последнюю на основе значения метки времени?
2. @РусланХ — Значения временных меток отсортированы?
3. они не отсортированы
4. @РусланХ — Ок, добавлено решение для ответа.
Ответ №2:
Вы можете сделать:
df = df.sort_values(['user_id', 'timestamp'])
df1=pd.DataFrame({'user_id':np.unique(df['user_id']),'event_name':'End','timestamp':np.NaN})
df=pd.concat([df,df1],axis=0).sort_values(by='user_id')
df['timestamp']=df['timestamp'].fillna(method='ffill')