还在手动筛选班级→复制→粘贴→算平均?Python让你一行代码搞定所有分组统计!
一、先看这个真实场景
李教研每次期中考试后都要干这些事:
以前她得:
- 筛选出“三(1)班”→复制到新表→算平均分→记下来 ✓
- 筛选出“三(2)班”→复制到新表→算平均分→记下来 ✓
- 筛选出“三(3)班”→复制到新表→算平均分→记下来 ✓
20个班就要重复20次!!!
二、Python的“分堆”魔法
今天教你1行代码,完成20个班的统计:
import pandas as pd# 假设你有全校成绩表成绩表 = pd.read_excel('全校期中成绩.xlsx')# 魔法开始!按班级分组,计算语文平均分各班语文平均 = 成绩表.groupby('班级')['语文'].mean()print("✅ 一键搞定20个班的语文平均分:")print(各班语文平均)
看懂了吗?
- .groupby('班级'):告诉Python“按班级把数据分成一堆一堆的”
整个过程:分堆→取列→计算 → 一行代码!
三、分解“魔法”:每步在干什么?
3.1 先建一个测试数据
import pandas as pd成绩表 = pd.DataFrame({'姓名': ['小明', '小红', '小刚', '小丽', '小华', '小强'],'班级': ['三(1)', '三(1)', '三(2)', '三(2)', '三(3)', '三(3)'],'语文': [85, 92, 78, 90, 88, 95],'数学': [92, 88, 85, 95, 90, 82],'英语': [88, 85, 80, 92, 87, 90]})print("📋 原始成绩表:")print(成绩表)
3.2 第一步:分堆(groupby)
分组对象 = 成绩表.groupby('班级')
这时候 Python 并没有计算任何东西,只是把数据按班级分成3堆:
3.3 第二步:从每堆取列 + 计算
# 每堆的语文平均分各班语文平均 = 分组对象['语文'].mean()print("📊 各班语文平均分:")print(各班语文平均)# 每堆的数学最高分各班数学最高 = 分组对象['数学'].max()print("\n📈 各班数学最高分:")print(各班数学最高)# 每堆的英语最低分各班英语最低 = 分组对象['英语'].min()print("\n📉 各班英语最低分:")print(各班英语最低)
运行结果:
📊 各班语文平均分:班级三(1) 88.5三(2) 84.0三(3) 91.5Name: 语文, dtype: float64
发现了没?
四、常用分组统计:一次算出多个指标
# 按班级分组,同时算出语文的平均分、最高分、最低分、人数班级语文统计 = 成绩表.groupby('班级')['语文'].agg(['mean', 'max', 'min', 'count'])print("📋 各班语文详细统计:")print(班级语文统计)
运行结果:
mean max min count班级 三(1) 88.5 92 85 2三(2) 84.0 90 78 2三(3) 91.5 95 88 2
- .agg(['mean', 'max', 'min', 'count'])
五、对多列分别做不同统计
# 对语文算平均分,对数学算最高分,对英语算最低分各科统计 = 成绩表.groupby('班级').agg({'语文': 'mean','数学': 'max','英语': 'min'})print("📊 各班级不同科目统计:")print(各科统计)
运行结果:
班级 语文 数学 英语 三(1) 88.5 92 85三(2) 84.0 95 80三(3) 91.5 90 90
关键点:
六、分组后保留原始列(transform)
有时候你想在原表里新增一列,比如“每个学生所在班级的语文平均分”,用来和自己成绩比较:
# 计算每个学生所在班级的语文平均分,并添加到原表成绩表['班级语文平均'] = 成绩表.groupby('班级')['语文'].transform('mean')print("📋 新增“班级平均分”列:")print(成绩表[['姓名', '班级', '语文', '班级语文平均']])
运行结果:
姓名 班级 语文 班级语文平均0 小明 三(1) 85 88.51 小红 三(1) 92 88.52 小刚 三(2) 78 84.03 小丽 三(2) 90 84.04 小华 三(3) 88 91.55 小强 三(3) 95 91.5
- .transform() 和 .agg() 的区别:
- .transform():返回和原表行数一样的结果,自动对齐
七、办公实战1:按班级统计总分和排名
# 先算每个人的总分成绩表['总分'] = 成绩表['语文'] + 成绩表['数学'] + 成绩表['英语']# 按班级分组,计算每班总分平均、最高、最低班级总分统计 = 成绩表.groupby('班级')['总分'].agg(['mean', 'max', 'min'])print("🏆 各班总分统计:")print(班级总分统计)
运行结果:
班级 mean max min 三(1) 264.0 265 263三(2) 261.5 277 246三(3) 267.0 267 267 # 小华小强总分一样都是267
八、办公实战2:按年级统计教师工作量
# 模拟教师课时数据教师表 = pd.DataFrame({'姓名': ['张老师', '李老师', '王老师', '赵老师', '刘老师'],'年级': ['一年级', '二年级', '一年级', '二年级', '三年级'],'科目': ['语文', '数学', '数学', '语文', '英语'],'课时': [18, 16, 20, 15, 14]})# 按年级统计平均课时、总课时年级统计 = 教师表.groupby('年级')['课时'].agg(['mean', 'sum', 'count'])年级统计 = 年级统计.rename(columns={'mean': '平均课时', 'sum': '总课时', 'count': '教师人数'})print("👨🏫 各年级教师课时统计:")print(年级统计)
运行结果:
年级 平均课时 总课时 教师人数 一年级 19.0 38 2二年级 15.5 31 2三年级 14.0 14 1
九、办公实战3:按月统计销售业绩
# 模拟全年销售数据销售表 = pd.DataFrame({'月份': ['1月', '1月', '2月', '2月', '3月', '3月'],'销售员': ['张三', '李四', '张三', '李四', '张三', '李四'],'销售额': [12000, 15000, 11000, 16000, 13000, 17000]})# 按月统计总销售额、平均销售额月度统计 = 销售表.groupby('月份')['销售额'].agg(['sum', 'mean'])月度统计.columns = ['总销售额', '平均销售额']print("💰 各月销售统计:")print(月度统计)
运行结果:
月份 总销售额 平均销售额 1月 27000 13500.02月 27000 13500.03月 30000 15000.0
十、分组统计常用函数速查
| |
|---|
| df.groupby('A')['B'].mean() |
| df.groupby('A')['B'].sum() |
| df.groupby('A')['B'].max() |
| df.groupby('A')['B'].min() |
| df.groupby('A')['B'].count() |
| df.groupby('A')['B'].std() |
| df.groupby('A')['B'].agg(['mean','max','min']) |
| df.groupby('A').agg({'B':'mean','C':'sum'}) |
| df.groupby('A')['B'].transform('mean') |
十一、重点总结:今天你学会了什么?
✅ 核心技能
- .mean()、.sum()、.max() - 对每堆计算
- .transform() - 在原表添加分组计算结果
✅ 办公应用场景
✅ 效率对比
十二、今日挑战:动手做!
任务1:按性别统计平均分
# 用下面的数据,按性别分组,计算语文、数学、英语的平均分学生 = pd.DataFrame({'姓名': ['张三', '李四', '王五', '赵六', '钱七'],'性别': ['男', '女', '男', '女', '男'],'语文': [78, 92, 85, 88, 90],'数学': [82, 94, 79, 91, 86],'英语': [80, 90, 88, 85, 92]})# 你的代码写在这里:
任务2:统计每个班级的优秀人数(语文≥90)
# 已有成绩表,需要先判断是否优秀,再按班级统计人数成绩表['语文优秀'] = 成绩表['语文'] >= 90# 按班级统计语文优秀人数:
任务3:在原表添加“本班数学平均分”列
# 使用成绩表,为每个学生添加一列,显示他所在班级的数学平均分
十三、明日预告
明天学数据透视表!
一行代码搞定透视表,比Excel拖拽还快!
回复「Py-Day」获取今日挑战题解答案及相关完整代码。
评论区作业:分享你工作中需要分组统计的场景,或者晒出你的运行截图!👇