Как добавить строку на основе последнего пользовательского события в pandas?

#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')