我在熊猫中有两个表,一个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
查询对我不起作用,我不确定下一步该怎么做。
答案 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