Pandas如何对无聚合数值列的两列DataFrame实现状态计数透视
你之前跑pivot_table得不到预期效果的核心原因是漏了关键参数:没有把PackageStatus指定为列维度的拆分依据,pandas自然只会把所有状态下的记录合并计算总计数,不会把不同状态值摊成单独的列。
针对这种两个分类变量交叉计数的场景,有三种常用的实现方式,都不需要额外的数值列做聚合:
方法1:补全参数修正pivot_table写法
pivot_table本身完全适配这类无额外数值列的计数场景,只要补上columns参数指定拆分列,配合空值填充即可直接得到目标格式:
pivot_result = ( df1.pivot_table( index="StoreId", # 行维度:按门店拆分 columns="PackageStatus", # 列维度:把状态值作为新列头 aggfunc="count", # 聚合逻辑:按非空值计数 fill_value=0 # 未出现的状态直接填0 ) .reset_index() # 把StoreId从行索引变回普通列,对齐预期输出格式 )
方法2:用crosstab实现专用列联表计数
pd.crosstab是pandas专门用来统计两个分类变量交叉出现频次的接口,写法比pivot_table更简洁,天生适配这类计数需求:
crosstab_result = ( pd.crosstab( index=df1["StoreId"], columns=df1["PackageStatus"], fill_value=0 ) .reset_index() )
方法3:分组聚合后做列旋转
如果习惯用groupby的逻辑链路,也可以先按两个分类字段分组计数,再把状态列旋转为宽表列:
groupby_result = ( df1.groupby(["StoreId", "PackageStatus"]) .size() # 直接统计每组的行数,不需要依赖额外数值列 .unstack(fill_value=0) # 把第二级索引(状态值)旋转为新列 .reset_index() )
以上三种方法运行后得到的结果,和你预期的输出格式完全一致:每个门店对应一行,各状态列填对应状态的出现次数,未出现的状态自动记为0。
内容的提问来源于stack exchange,提问作者FMFF
相关产品推荐
相关产品推荐

