pandas groupby 列表长度

pandas groupby with length of lists

我需要在数据框列中显示 user_id 和 content_id 的长度,这是一个列表对象。但是很难使用groupby。 请帮助 groupby 以及我在 post 底部提出的问题(如何在数据框中获得结果以及 user_id?)

数据帧类型:

df.dtypes

输出:

user_id       object
content_id    object
dtype: object

示例数据:

    user_id     content_id
0   user_18085  [cont_2598_4_4, cont_2738_2_49, cont_4482_2_19...
1   user_16044  [cont_2738_2_49, cont_4482_2_19, cont_4994_18_...
2   user_13110  [cont_2598_4_4, cont_2738_2_49, cont_4482_2_19...
3   user_18909  [cont_3170_2_28]
4   user_15509  [cont_2598_4_4, cont_2738_2_49, cont_4482_2_19...

Pandas查询:

df.groupby('user_id')['content_id'].count().reset_index()

df.groupby(['user_id'])['content_id'].apply(lambda x: get_count(x))

输出:

    user_id     content_id
0   user_10013  1
1   user_10034  1
2   user_10042  1

当我尝试不分组时,我变得很好,如下所示 -

df['content_id'].apply(lambda x: len(x))


0       11
1        9
2       11
3        1

但是,如何在数据框中获取结果以及 user_id?就像我想要的格式 -

user_id   content_id
some xxx  11
some yyy  6
  

pandas.Groupby returns一个石斑鱼元素不是每个单元格的内容。因此,不可能(没有很多解决方法)做你想做的事。相反,您需要简单地重写列(如@ifly6 所建议)

正在使用

df_agg = df.copy()
df_agg.content_id = df_agg.content_id.apply(len)
df_agg = df_agg.groupby('user_id').sum()

将产生与您描述的 Groupby 相同的数据帧。

为了完整起见,单个 groupby 的指令将是

df.groupby('user_id').agg(lambda x: x.apply(len).sum())

尝试将 content_id 转换为字符串,用逗号分隔,然后重新组合为列表列表,然后对列表项进行计数。

data="""index  user_id     content_id
0   user_18085  [cont_2598_4_4,cont_2738_2_49,cont_4482_2_19]
1   user_16044  [cont_2738_2_49,cont_4482_2_19,cont_4994_18_]
2   user_13110  [cont_2598_4_4,cont_2738_2_49,cont_4482_2_19]
3   user_18909  [cont_3170_2_28]
4   user_15509  [cont_2598_4_4,cont_2738_2_49,cont_4482_2_19]
"""
df = pd.read_csv(StringIO(data), sep='\s+')

def convert_to_list(x):
    x=re.sub(r'[\[\]]', '', x)
    lst=list(x.split(','))
    return lst

df['content_id2']= [list() for x in range(len(df.index))]
for key,item in df.iterrows():
    lst=convert_to_list(str(item['content_id']))
    for item in lst:
        df.loc[key,'content_id2'].append(item)
    
def count_items(x):
    return len(x)

df['count'] = df['content_id2'].apply(count_items)
df.drop(['content_id'],axis=1,inplace=True)
df.rename(columns={'content_id2':'content_id'},inplace=True)
print(df)

输出:

 index     user_id                                       content_id  count
0      0  user_18085  [cont_2598_4_4, cont_2738_2_49, cont_4482_2_19]      3
1      1  user_16044  [cont_2738_2_49, cont_4482_2_19, cont_4994_18_]      3
2      2  user_13110  [cont_2598_4_4, cont_2738_2_49, cont_4482_2_19]      3
3      3  user_18909                                 [cont_3170_2_28]      1
4      4  user_15509  [cont_2598_4_4, cont_2738_2_49, cont_4482_2_19]      3
​