熊猫:分组并从表中查找最近的事件,然后与现有表一起加入?

时间:2018-08-10 14:52:00

标签: python pandas dataframe

我在熊猫中有两个表,一个user表和一个history表-后者实质上是用户执行的所有操作的日志。

用户表:

   |  user_id  |  source
0  |  1        |  blog
1  |  2        |  blog
2  |  3        |  organic

历史记录表:

   |  user_id  |  action_type  |  t_actioned
0  |  1        |  332          |  2018-08-04 12:35:23   
1  |  1        |  453          |  2018-08-04 12:36:23   
2  |  1        |  332          |  2018-08-04 12:38:23   
3  |  2        |  452          |  2018-08-04 12:40:23   
4  |  3        |  523          |  2018-08-04 12:41:23   
5  |  2        |  452          |  2018-08-04 12:41:43   

我想从history表中找到每个用户最新操作的时间戳,并将其作为新列添加到user表中。

我该怎么做?

看着this answer,我认为这就像:

 # Get the latest action by user
 first_action = history.group_by('user_id').agg(lambda df: df.sort('t_actioned')[-1:].values[0])
 user.first_action = # join with first_action somehow?

但是agg查询对我不起作用,我不确定下一步该怎么做。

3 个答案:

答案 0 :(得分:4)

首先进行排序,删除重复项并根据您的历史记录数据帧创建一个系列:

s = history.sort_values('t_actioned', ascending=False)\
           .drop_duplicates('user_id')\
           .set_index('user_id')['action_type']

然后将其映射到您的用户数据框:

user['action_type'] = user['user_id'].map(s)

如注释中所指出的,如果您的日志已经排序,则可以避免使用sort_values并使用drop_duplicates('user_id', keep='last')

答案 1 :(得分:3)

您可以利用以下事实:在构造具有多个重复键的字典时,您只会保留最后一个。

m = dict(history.sort_values('t_actioned').pipe(
    lambda d: zip(d.user_id, d.t_actioned)))

user.assign(latest=user.user_id.map(m))

   user_id   source               latest
0        1     blog  2018-08-04 12:38:23
1        2     blog  2018-08-04 12:41:43
2        3  organic  2018-08-04 12:41:23

考虑数据的简短版本已按't_actioned'排序

user.assign(latest=user.user_id.map(dict(zip(history.user_id, history.t_actioned))))

答案 2 :(得分:0)

另一种方式:

history = history.groupby(['user_id']).apply(lambda x: x.sort_values('t_actioned', ascending = False))
history = history.drop_duplicates(subset = ['user_id'], keep = 'first')
user = pd.merge(user, history[['t_actioned']], on = 'user_id', how = 'left')

输出:

   user_id   source          t_actioned
0        1     blog 2018-08-04 12:38:23
1        2     blog 2018-08-04 12:41:43
2        3  organic 2018-08-04 12:41:23