在Pandas中混合使用聚合与Group By的实现问题
解决配送司机配送结果统计问题
首先得指出你当前代码的两个核心问题:一是原始数据里的列名是Outcome(首字母大写),你写的是小写outcome,这会导致程序找不到对应列报错;二是就算列名正确,groupby(['Name','Outcome']).agg(['count'])得到的是长表格式的分层索引结果,不是你想要的宽表(每个姓名一行、Pass/Fail作为列)。
下面给你几个能直接生成预期表格的实用方案:
方法1:用pivot_table(最直观)
这个方法可以直接把Outcome的不同值转成列,自动统计数量,还能填充缺失的0:
# 基于原始数据集生成透视表,size用来统计数量,fill_value填充缺失值为0 result = report.pivot_table(index='Name', columns='Outcome', aggfunc='size', fill_value=0) # 新增Total列,计算每行Pass和Fail的总和 result['Total'] = result.sum(axis=1) # 调整列顺序并重置索引,让Name变回普通列 result = result[['Pass', 'Fail', 'Total']].reset_index()
运行后就能得到你想要的统计表格。
方法2:用pd.crosstab
crosstab是Pandas专门用于交叉统计的工具,操作同样简洁:
import pandas as pd # 生成姓名与配送结果的交叉统计表,fillna(0)确保缺失值显示为0 result = pd.crosstab(report['Name'], report['Outcome']).fillna(0).astype(int) # 添加Total列 result['Total'] = result.sum(axis=1) # 调整列顺序并重置索引 result = result[['Pass', 'Fail', 'Total']].reset_index()
方法3:基于你的groupby逻辑修改
如果你一定要保留groupby的思路,需要把分组后的结果通过unstack转成宽表,再处理缺失值:
# 注意列名是大写的Outcome,size统计分组数量 grouped = report.groupby(['Name', 'Outcome']).size().unstack(fill_value=0) # 新增Total列 grouped['Total'] = grouped.sum(axis=1) # 调整列顺序并重置索引 grouped = grouped[['Pass', 'Fail', 'Total']].reset_index()
最终输出的结果都会和你预期的表格完全一致:
| Name | Pass | Fail | Total |
|---|---|---|---|
| A | 1 | 1 | 2 |
| B | 0 | 1 | 1 |
| C | 2 | 0 | 2 |
| D | 1 | 0 | 1 |
内容的提问来源于stack exchange,提问作者Nithin Nampoothiry
相关产品推荐
相关产品推荐

