Pandas多列分组透视求助:按用户+月份统计活动次数报错
解决多维度交叉统计(ID、月份、活动次数)
你的需求是统计每个用户(id)在不同月份(month)下,各类活动(activity)的发生次数,直接用pd.crosstab传入多级行索引就能实现,也可以通过pivot_table或分组统计来完成。
原始数据回顾
你的DataFrame结构如下:
import pandas as pd df = pd.DataFrame({'id': ['id1', 'id1','id1', 'id2','id1','id1','id1'], 'activity':['swimming','running','jogging','walking','walking','walking','walking'], 'month':[2,3,4,3,4,4,3]})
正确实现方法
方法1:使用pd.crosstab(最直接)
将行索引设置为id和month的组合,列设置为activity,直接得到交叉统计结果:
# 生成交叉表,缺失值填充为0 result = pd.crosstab([df['id'], df['month']], df['activity'], dropna=False, margins=False) # 把多级索引转为普通列 result = result.reset_index() print(result)
输出结果:
activity id month jogging running swimming walking 0 id1 2 0 0 1 0 1 id1 3 0 1 0 1 2 id1 4 1 0 0 2 3 id2 3 0 0 0 1
方法2:使用pivot_table
通过透视表实现相同效果,指定索引、列和统计函数:
result = df.pivot_table( index=['id', 'month'], columns='activity', aggfunc='size', # 统计每组数量 fill_value=0 # 缺失活动填充为0 ).reset_index() print(result)
方法3:分组统计后unstack
先按id、month、activity分组计数,再将activity转为列:
result = df.groupby(['id', 'month', 'activity']).size().unstack(fill_value=0).reset_index() print(result)
为什么你的代码报错?
你执行的df.set_index(['id','month'])['activity'].unstack().reset_index()会报错,原因是:
- 将
id和month设为索引后,activity是一个包含重复索引(同一个(id,month)对应多个activity值)的Series,unstack()要求索引唯一才能重塑结构,因此会触发ValueError: Index contains duplicate entries, cannot reshape。 - 即使索引唯一,
unstack()默认会把最内层索引(month)转为列,这和你想要的“activity作为列”的需求方向不符。
内容的提问来源于stack exchange,提问作者Death Metal
相关产品推荐
相关产品推荐

