Pandas groupby两列,只保留满足条件的记录

时间:2018-05-13 23:30:55

标签: python pandas dataframe pandas-groupby

如果操作数达到阈值,请尝试过滤用户已执行的许多操作。

以下是数据集:(仅少数记录)

user_id,session_id,item_id,rating,length,time
123,36,28,3.5,6243.0,2015-03-07 22:44:40
123,36,29,2.5,4884.0,2015-03-07 22:44:14
123,36,30,3.5,6846.0,2015-03-07 22:44:28
123,36,54,6.5,10281.0,2015-03-07 22:43:56
123,36,61,3.5,7639.0,2015-03-07 22:43:44
123,36,62,7.5,18640.0,2015-03-07 22:43:34
123,36,63,8.5,7189.0,2015-03-07 22:44:06
123,36,97,2.5,7627.0,2015-03-07 22:42:53
123,36,98,4.5,9000.0,2015-03-07 22:43:04
123,36,99,7.5,7514.0,2015-03-07 22:43:13
223,63,30,8.0,5412.0,2015-03-22 01:42:10
123,36,30,5.5,8046.0,2015-03-07 22:42:05
223,63,32,8.5,4872.0,2015-03-22 01:42:03
123,36,32,7.5,11914.0,2015-03-07 22:41:54
225,63,35,7.5,6491.0,2015-03-22 01:42:19
123,36,35,5.5,7202.0,2015-03-07 22:42:15
123,36,36,6.5,6806.0,2015-03-07 22:42:43
123,36,37,2.5,6810.0,2015-03-07 22:42:34
225,63,41,5.0,15026.0,2015-03-22 01:42:37
225,63,45,6.5,8532.0,2015-03-07 22:42:25

我可以使用groupbyuser_id session_id获取数据,并获得用户在会话中评价的count项:

df.groupby(['user_id', 'session_id']).agg({'item_id':'count'}).rename(columns={'item_id': 'count'})

可以获得用户在会话中评分的项目列表:

df.groupby(['user_id','session_id'])['item_id'].apply(list)

如果用户在会话中评价超过3个项目,我的目标是获得关注,我想从原始数据框中仅选择前三个项目(每个会话仅保留每个用户的前三个项目)。也许用时间对项目进行排序?

首先尝试获得哪些会话包含3个以上,有点难以超越。

df.groupby(['user_id', 'session_id'])['item_id'].apply(
            lambda x: (x > 3).count())

示例:从原始df开始,用户123应该有前三个记录属于会话36

2 个答案:

答案 0 :(得分:2)

您似乎希望将groupbyhead一起使用:

In [8]: df.groupby([df.user_id, df.session_id]).head(3)
Out[8]:
    user_id  session_id  item_id  rating   length                 time
0       123          36       28     3.5   6243.0  2015-03-07 22:44:40
1       123          36       29     2.5   4884.0  2015-03-07 22:44:14
2       123          36       30     3.5   6846.0  2015-03-07 22:44:28
10      223          63       30     8.0   5412.0  2015-03-22 01:42:10
12      223          63       32     8.5   4872.0  2015-03-22 01:42:03
14      225          63       35     7.5   6491.0  2015-03-22 01:42:19
18      225          63       41     5.0  15026.0  2015-03-22 01:42:37
19      225          63       45     6.5   8532.0  2015-03-07 22:42:25

答案 1 :(得分:1)

一种方法是使用sort_values后跟groupby.cumcount。我觉得有用的方法是在应用任何过滤之前提取任何系列或MultiIndex数据。

以下示例过滤了3个项目的最小user_id / session_id组合,并且只取每组中的前3个。

sizes = df.groupby(['user_id', 'session_id']).size()
counter = df.groupby(['user_id', 'session_id']).cumcount() + 1  # counting begins at 0
indices = df.set_index(['user_id', 'session_id']).index

df = df.sort_values('time')
res = df[(indices.map(sizes.get) >= 3) & (counter <=3)]

print(res)

    user_id  session_id  item_id  rating   length                 time
0       123          36       28     3.5   6243.0  2015-03-07 22:44:40
1       123          36       29     2.5   4884.0  2015-03-07 22:44:14
2       123          36       30     3.5   6846.0  2015-03-07 22:44:28
14      225          63       35     7.5   6491.0  2015-03-22 01:42:19
18      225          63       41     5.0  15026.0  2015-03-22 01:42:37
19      225          63       45     6.5   8532.0  2015-03-07 22:42:25