熊猫,groupby,但最多可达到一定数量

时间:2019-03-18 03:17:53

标签: pandas

我有一个用户行为数据。用户查看项目。

user_id, item_id, timestamp
1, a, 1000
2, b, 1001
1, c, 1002
1, d, 1004
1, e, 1005
1, a, 1006
2, f, 1007

从概念上讲,我将这种查看操作视为在会话中发生的,并希望构建一个会话。

(如果可以的话,我可以看一下时间戳,并可以用它定义会话,但是为了简单起见,我只是用固定的窗口大小进行分区)

对于窗口大小= 3,跨度= 1(在示例中将很清楚),我想将数据转换为以下格式

user_id, items 
1, [a,c,d]
2, [b,f]
1, [d, e, a]

因此,对于user_id 1,他/她的第一会话包括查看[a,c,d],第二会话[d,e,a]。重复d是因为stride = 1,如果stride为2,则第二个会话将是[c,d,e]

(当您按窗口大小对数据进行分区时,我希望窗口彼此重叠且大小等于步幅)

如果stride实施起来很麻烦,那么我就放弃它。 (之所以在这里,是因为我要对会话进行分区,并且不想丢失顺序信息)

1 个答案:

答案 0 :(得分:0)

这是应该起作用的功能。 (我不保证它在stride > gsize时的表现会达到您的预期)。我对stride的定义略有不同。我将其作为自开始进行新分组以来的观察次数:

import pandas as pd

def rolling_list(x, stride=1, gsize=3):
    if len(x) <= gsize:
        l = [list(x.to_list())]
    else:
        l = [x.iloc[i*stride:(i*stride)+gsize].to_list()
             for i in range(len(x)//gsize+(gsize-stride))]
    return pd.Series(l)

df.groupby('user_id').item_id.apply(rolling_list, stride=1)

#user_id   
#1        0    [a, c, d]
#         1    [c, d, e]
#         2    [d, e, a]
#         3    [e, a, z]
#2        0       [b, f]

df.groupby('user_id').item_id.apply(rolling_list, stride=2)
#user_id   
#1        0    [a, c, d]
#         1    [d, e, a]
#         2       [a, z]
#2        0       [b, f]
#Name: item_id, dtype: object

样本数据(添加了额外的一行)

user_id,item_id,timestamp
1,a,1000
2,b,1001
1,c,1002
1,d,1004
1,e,1005
1,a,1006
2,f,1007
1,z,1008