Pandas如何对DataFrame分组并将类别字段转为列统计计数
Pandas分组统计转宽表实现方案
要实现按setting分组、统计分组总记录数+各status类型计数、缺失status类别补0的宽表输出,用pd.crosstab(交叉统计表)实现最简便,不需要先生成groupby长表再转换,可直接一步出结果。
具体实现步骤
- 先定义固定的
status枚举值列表,保证即使数据集缺失某类status,最终输出也会保留对应列 - 将
status列转为pandas分类类型,绑定固定枚举值,避免统计时漏掉缺失的类别 - 用crosstab以
setting为行、status为列做计数统计 - 新增
total列,对每行各status的计数求和得到分组总记录数 - 调整列顺序匹配目标输出格式
完整代码
import pandas as pd # 构造原始数据集 lst = [ ['s001','b1','typeA'],['s002','b1','typeB'],['s003','b1','typeC'],['s004','b1','typeD'], ['s005','b1','typeA'],['s006','b1','typeB'],['s007','b1','typeC'],['s008','b1','typeD'], ['s009','b2','typeA'],['s010','b2','typeB'],['s011','b2','typeC'] ] df = pd.DataFrame(lst, columns=['sn','setting','status']) # 定义固定的status类型 fixed_status_types = ['typeA', 'typeB', 'typeC', 'typeD'] # 将status列转为绑定固定类别的分类类型,缺失类别自动补0 df['status'] = pd.Categorical(df['status'], categories=fixed_status_types) # 生成交叉统计宽表 result = pd.crosstab( index=df['setting'], columns=df['status'], dropna=False ).reset_index() # 计算分组总记录数 result['total'] = result[fixed_status_types].sum(axis=1) # 调整列顺序,和期望输出对齐 result = result[['setting', 'total'] + fixed_status_types]
输出结果
运行代码后得到的result内容如下,和预期格式完全一致(注:给出的期望输出里存在笔误,将typeA错写为tppeA,结果中已修正为正确列名):
setting total typeA typeB typeC typeD 0 b1 8 2 2 2 2 1 b2 3 1 1 1 0
其他可选写法
如果更习惯用groupby的逻辑,也可以先分组计数再转透视表,但需要手动补全缺失的status列填0,代码会稍繁琐:
# 分组计数后转透视表 pivot_df = df.groupby(['setting','status']).size().unstack(fill_value=0) # 补全可能缺失的status列 for col in fixed_status_types: if col not in pivot_df.columns: pivot_df[col] = 0 # 计算total并重设索引 pivot_df['total'] = pivot_df[fixed_status_types].sum(axis=1) pivot_df = pivot_df.reset_index()[['setting','total']+fixed_status_types]
两种写法最终输出结果完全一致。
内容的提问来源于stack exchange,提问作者Niuya
相关产品推荐
相关产品推荐

