当前位置: 首页 > news >正文

groupby + agg:数据分析 80% 的活就这两招

groupby + agg:数据分析 80% 的活就这两招

“各品类销售额多少?” “每个月的 GMV 趋势?” “各部门绩效排名?”

这些问题的答案,都是 groupby + 聚合。

Excel 里你要拉透视表、写 SUMIF,Pandas 里就两行。

groupby 的本质:分—算—合

importpandasaspdimportnumpyasnp df=pd.DataFrame({"部门":["技术","销售","技术","销售","技术","销售","市场","市场"],"姓名":["张三","李四","王五","赵六","孙七","周八","吴九","郑十"],"薪资":[15000,12000,18000,14000,20000,13000,11000,10000],"绩效":[85,92,78,88,95,80,90,85],})# 各部门平均薪资print(df.groupby("部门")["薪资"].mean())# 部门# 技术 17666.67# 市场 10500.00# 销售 13000.00

三步骤:按"部门"分组 → 对"薪资"求均值 → 合并输出。

常用聚合函数

grouped=df.groupby("部门")print(grouped["薪资"].sum())# 求和print(grouped["薪资"].mean())# 均值print(grouped["薪资"].median())# 中位数print(grouped["薪资"].max())# 最大值print(grouped["薪资"].min())# 最小值print(grouped["薪资"].std())# 标准差print(grouped["薪资"].count())# 计数print(grouped["薪资"].nunique())# 唯一值个数

agg:一次算多个指标

# 对薪资同时算均值和总和result=df.groupby("部门")["薪资"].agg(["mean","sum","count"])result.columns=["平均薪资","总薪资","人数"]print(result)# 对不同列算不同指标result=df.groupby("部门").agg({"薪资":["sum","mean"],"绩效":["mean","max","min"],})print(result)# 自定义聚合函数defrange_func(x):returnx.max()-x.min()result=df.groupby("部门").agg({"薪资":range_func})print(result)

多级分组

# 模拟更大数据集np.random.seed(42)sales=pd.DataFrame({"year":np.random.choice([2024,2025,2026],100),"quarter":np.random.choice(["Q1","Q2","Q3","Q4"],100),"category":np.random.choice(["手机","电脑","耳机"],100),"amount":np.random.randint(1000,10000,100)})# 多列 groupbyresult=sales.groupby(["year","category"])["amount"].sum()print(result)# unstack 转成透视表格式pivot=result.unstack()print(pivot)# 透视表一步到位pivot=pd.pivot_table(sales,values="amount",index="year",columns="category",aggfunc="sum",fill_value=0)print(pivot)

transform:保持原形状

# transform 返回和原始数据一样长的结果df=pd.DataFrame({"部门":["技术","销售","技术","销售","技术"],"薪资":[15000,12000,18000,14000,20000]})# 每人薪资 vs 部门平均df["部门均值"]=df.groupby("部门")["薪资"].transform("mean")df["与均值差"]=df["薪资"]-df["部门均值"]print(df)

agg返回的是分组后的汇总值(行数变少),transform返回的是和原始数据一样长的值。

apply:最灵活

# 每个部门薪资最高的那个人deftop_earner(group):returngroup.nlargest(1,"薪资")result=df.groupby("部门",group_keys=False).apply(top_earner)print(result)# 给每个部门的薪资排序(组内排名)df["组内排名"]=df.groupby("部门")["薪资"].rank(ascending=False)print(df)

实战:销售数据分析

np.random.seed(123)dates=pd.date_range("2026-01-01","2026-06-30",freq="D")sales=pd.DataFrame({"date":np.random.choice(dates,500),"product":np.random.choice(["手机","电脑","耳机","平板"],500),"city":np.random.choice(["北京","上海","广州","深圳"],500),"amount":np.random.randint(500,15000,500),})# 各产品总销售额print("=== 产品销售额排名 ===")print(sales.groupby("product")["amount"].sum().sort_values(ascending=False))# 每月销售额趋势sales["month"]=sales["date"].dt.to_period("M")monthly=sales.groupby("month")["amount"].sum()print(f"\n=== 月度销售额 ===\n{monthly}")# 每城市最畅销产品city_product=sales.groupby(["city","product"])["amount"].sum()print(f"\n=== 深圳最畅销 ===\n{city_product.loc['深圳'].sort_values(ascending=False)}")# 各产品的客单价和订单数stats=sales.groupby("product").agg(总销售额=("amount","sum"),订单数=("amount","count"),客单价=("amount","mean"),最高单=("amount","max")).round(1)print(f"\n=== 综合统计 ===\n{stats}")

新手常见坑

坑1:groupby 结果索引

# groupby 结果可能有多级索引result=sales.groupby(["city","product"])["amount"].sum()# 用 reset_index 展平result=result.reset_index()

坑2:NaN 被分组忽略

# 如果分组列有 NaN,那行不会被计入任何组# 先 fillna 再 groupbydf["city"]=df["city"].fillna("未知")

坑3:agg 里写错函数名

# ❌ 函数名是字符串# df.groupby("x").agg("average") # 没有这个# ✅ 正确的 Pandas 聚合函数名df.groupby("x").agg("mean")

动手试试

  1. 按"部门"分组,计算薪资的总和、均值、最大值、人数
  2. 用 pivot_table 做一个按"年份"和"季度"交叉的销售额表
  3. 用 transform 给每个员工加上"组内排名"

写在最后

groupby + agg 就是 Pandas 的透视表引擎。80% 的数据分析问题能用这两招解决。多练、多试,手感到了就熟了。

下一篇讲 DataFrame 的合并——merge、concat、join,多张表怎么优雅地拼在一起。

http://www.jsqmd.com/news/1128864/

相关文章:

  • 5个理由告诉你为什么VIA是机械键盘配置的终极选择
  • YOLO目标检测全栈实战:从v1到v13算法精讲与项目部署指南
  • AWS、微软、谷歌和 Anthropic 悄悄做了同一件事:Session 正在取代请求,成为 Agent 的新计算单元
  • HTTP(HyperText Transfer Protocol,超文本传输协议)是位于OSI七层模型和TCP/IP四层模型中**应用层**的协议
  • 终极Wand-Enhancer完全指南:5分钟解锁游戏修改器完整高级功能
  • 不同进程的线程切换**不一定引起进程切换**,但**必然涉及进程上下文切换(即进程切换)**——这里需要明确概念辨析
  • 55-LangChain核心概念-Chain-Agent-Tool-Memory关系
  • 从0到1用C#开发ABB机器人上位机:PC SDK通信+运动控制+状态监控
  • PyTorch 2.0+ 实战:Fashion MNIST 图像分类从 91% 到 95% 的 3 个调优技巧
  • XPS深度剖析概述
  • 2026全球汽车资本风向:为什么Tier 1供应商正在比主机厂赚得更多?
  • 测试框架体系 TDD DDT BDD ATDD 介绍
  • 2026年7月亲测,汽修引流这样干超有效!
  • 2026 AI 开发者生存指南(9):AI 产品的数据分析与增长方法——从流量到留存
  • WSL2 安装LeRebot开发环境
  • TVA在具身智能商业化部署中的技术突破(10)
  • 腾讯元宝复制内容带乱码怎么办?AI 导出鸭一键解决复制粘贴乱码难题,程序员高效办公必备
  • 论文学习:2.Semi-Supervised Classification with Graph Convolutional Networks(1)
  • Onekey Steam游戏解锁器:智能自动化DLC解锁的全面解决方案
  • Python练习题2
  • TPA3128D2音频放大器与PIC18F4458微控制器的集成应用
  • 26. 【C语言】编译前的“文本大师”:预处理器指令
  • 华盛顿邮报发文:中国企业正在改写全球 AI 竞争格局——不靠最顶尖,靠最实用
  • merge、concat、join:三张表合并搞崩你的不是语法是逻辑
  • 智慧职教自动化学习助手:让在线课程学习更高效
  • X射线光电子能谱(XPS)全元素深度剖析
  • 基于 Simulink 的双向 DC-DC 变换器效率 MAP 图自动化扫描仿真实
  • 医学图像分割神器TotalSegmentator:三步掌握100+解剖结构自动识别
  • 高效智能图像去重解决方案:ImageDedup 终极指南
  • STM32L433RC与MC6470 IMU的高精度姿态检测方案