You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()会报错,原因是:

  1. 将id和month设为索引后,activity是一个包含重复索引(同一个(id,month)对应多个activity值)的Series,unstack()要求索引唯一才能重塑结构,因此会触发ValueError: Index contains duplicate entries, cannot reshape。
  2. 即使索引唯一,unstack()默认会把最内层索引(month)转为列,这和你想要的“activity作为列”的需求方向不符。

内容的提问来源于stack exchange,提问作者Death Metal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:30:57