如何在Pandas中分组后将指定列值设为表头并统计计数?
解决方案:Pandas按指定列分组并将类别转为列统计次数
问题分析
你当前的代码用pd.crosstab([df["location"], df["box"]], df["type"])是按location+box的组合分组统计,但你的期望输出是仅按location汇总每个type的出现次数,核心问题是聚合维度不对,需要调整。
方法1:groupby + value_counts + unstack
这是最直观的实现方式,先按location分组统计type的频次,再将行索引的type转为列:
import pandas as pd # 构造示例数据 data = { "location": ["ny", "ny", "ny", "ny", "ny", "ca", "ca"], "box": ["box11", "box11", "box13", "box13", "box13", "box5", "box8"], "type": ["hey", "hey", "hello", "hello", "hello", "hi", "hello"] } df = pd.DataFrame(data) # 分组统计并转列 result = df.groupby("location")["type"].value_counts().unstack(fill_value=0).reset_index() result.columns.name = None # 移除列索引的冗余名称 print(result)
输出结果:
location hello hey hi 0 ca 1 0 1 1 ny 3 2 0
方法2:基于你的crosstab代码优化
如果想沿用crosstab的思路,可以先按location+box统计,再按location层级求和:
df2 = pd.crosstab([df["location"], df["box"]], df["type"]) # 按location分组求和,重置索引并清理列名 result = df2.groupby(level="location").sum().reset_index() result.columns.name = None print(result)
输出与方法1完全一致。
方法3:pivot_table 简洁实现
用pivot_table直接指定行、列和聚合逻辑,代码更紧凑:
result = pd.pivot_table(df, index="location", columns="type", values="box", aggfunc="count", fill_value=0).reset_index() result.columns.name = None print(result)
同样能得到符合预期的输出。
关键注意点
- 如果你实际需要保留
box维度的统计(比如按location+box分组),那你最初的crosstab代码是正确的;但根据你的期望输出,要去掉box的分组,只保留location。 fill_value=0是为了让不存在的type显示为0,避免出现NaN值。
内容的提问来源于stack exchange,提问作者Lynn
相关产品推荐
相关产品推荐

