查看: 124|回复: 3

Pandas pivot_table 从参数到电商实战:聚合与多维透视完全指南

[复制链接]
发表于 3 小时前 | 显示全部楼层 |阅读模式
数据分析中,面对原始流水数据,需要按多个维度分组汇总出二维报表。Pandas 的 pivot_table 能将分组、聚合、重塑三步合并为一行代码,是生成报表的最直接工具。本文从参数详解、基础示例、真实场景、横向对比到综合实战,完整演示 pivot_table 的核心用法。




核心参数说明

pivot_table 的签名为:
  1. pandas.pivot_table(
  2.     data,
  3.     values=None,
  4.     index=None,
  5.     columns=None,
  6.     aggfunc='mean',
  7.     fill_value=None,
  8.     margins=False,
  9.     dropna=True,
  10.     margins_name='All',
  11.     observed=False,
  12.     sort=True
  13. )
复制代码

每个参数的含义和注意事项:

- data:DataFrame,必填。
- values:str 或 list,要聚合的数值列;省略则对所有数值列聚合。
- index:str 或 list,行分组字段,传列表形成多层行索引。
- columns:str 或 list,列分组字段,传列表形成多层列索引。
- aggfunc:func / list / dict,默认 'mean',支持字符串、函数、列表、字典,字典语法可对不同列使用不同聚合函数。
- fill_value:标量,聚合后产生的 NaN 用此值填充。
- margins:bool,是否添加行列汇总(小计/总计)。
- dropna:bool,聚合前丢弃全为 NaN 的列。注意与 fill_value 顺序:先丢后填。
- margins_name:str,汇总行/列标签,可改为“合计”或“总计”。
- observed:bool,仅对 Categorical 类型有效,建议 pandas 2.2+ 设为 True 只显示实际出现的组合,避免产生全零行。
- sort:bool,结果是否排序(v1.3.0 新增)。




基础用法演示

先准备示例数据:
  1. import pandas as pd
  2. import numpy as np
  3. df = pd.DataFrame({
  4.     "A": ["foo", "foo", "foo", "foo", "foo", "bar", "bar", "bar", "bar"],
  5.     "B": ["one", "one", "one", "two", "two", "one", "one", "two", "two"],
  6.     "C": ["small", "large", "large", "small", "small", "large", "small", "small", "large"],
  7.     "D": [1, 2, 2, 3, 3, 4, 5, 6, 7],
  8.     "E": [2, 4, 5, 5, 6, 6, 8, 9, 9]
  9. })
复制代码

最基础用法:按 A、B 分行,按 C 分列,对 D 列求和:
  1. table = pd.pivot_table(df, values='D', index=['A', 'B'],
  2.                        columns=['C'], aggfunc="sum", fill_value=0)
  3. print(table)
复制代码

输出中原本缺失的组合(如 foo/two/large)用 fill_value=0 填充为 0。

对不同列使用不同聚合函数:
  1. table = pd.pivot_table(df, values=['D', 'E'], index=['A', 'C'],
  2.                        aggfunc={'D': 'mean', 'E': ['min', 'max', 'mean']})
  3. print(table)
复制代码

结果列变为多层索引,E 列下挂三个子列。




真实场景实战

1. 销售报表

按季度和地区汇总销售额与利润:
  1. data = {
  2.     '地区': ['华东', '华东', '华北', '华北', '华南', '华南'],
  3.     '产品': ['A', 'B', 'A', 'B', 'A', 'B'],
  4.     '季度': [1, 1, 1, 2, 2, 2],
  5.     '销售额': [150000, 120000, 90000, 110000, 130000, 95000],
  6.     '利润': [30000, 24000, 18000, 22000, 26000, 19000]
  7. }
  8. df_sales = pd.DataFrame(data)
  9. pivot = pd.pivot_table(
  10.     data=df_sales,
  11.     values=['销售额', '利润'],
  12.     index='季度',
  13.     columns='地区',
  14.     aggfunc='sum',
  15.     fill_value=0,
  16.     margins=True,
  17.     margins_name='总计'
  18. )
  19. print(pivot)
复制代码

b]2. 时间维度多层索引

将“地区”和“月份”作为行索引,产品作为列:
  1. df['月份'] = df['日期'].dt.month
  2. pivot = pd.pivot_table(
  3.     data=df,
  4.     index=['地区', '月份'],
  5.     columns='产品',
  6.     values='销售额',
  7.     aggfunc='sum'
  8. )
  9. # 用 xs 切片
  10. print(pivot.xs('华东', level='地区'))
复制代码

3. 用户行为多函数聚合

同时查看总访问量和人均次数:
  1. pivot = pd.pivot_table(
  2.     data=df_user,
  3.     index='用户等级',
  4.     columns='访问渠道',
  5.     values='访问次数',
  6.     aggfunc=['sum', 'mean'],
  7.     fill_value=0
  8. )
复制代码




高级技巧

自定义聚合函数:用 lambda 计算极差(最大值减最小值):
  1. pivot = pd.pivot_table(df, values='D', index='A',
  2.                        aggfunc=lambda x: x.max() - x.min())
复制代码

同时使用多个内置函数:
  1. pivot = pd.pivot_table(df, values='D', index='A',
  2.                        aggfunc=['sum', 'mean', 'count', np.std])
复制代码

扁平化多层列名:当 aggfunc 为列表/字典时,列索引变为 MultiIndex,可用列表推导压平:
  1. pivot.columns = ['_'.join(col).strip() for col in pivot.columns.values]
复制代码

链式操作:透视结果是标准 DataFrame,可直接接 reset_index、sort_values、query:
  1. result = (
  2.     pd.pivot_table(df, values='销售额', index='地区', aggfunc='sum')
  3.     .reset_index()
  4.     .sort_values('销售额', ascending=False)
  5.     .query('销售额 > 100000')
  6. )
复制代码




相近方法对比

| 方法 | 支持重复值 | 支持聚合 | 输出格式 | 适用场景 |
|------|-----------|---------|---------|---------|
| pivot() | ❌ | ❌ | 宽格式 | 数据唯一,纯重塑 |
| pivot_table() | ✅ | ✅ 灵活 | 宽格式 | 汇总报表、多维分析 |
| groupby() | ✅ | ✅ 灵活 | 长格式 | 分组统计,输出灵活 |
| crosstab() | ✅ | ✅ 默认频次 | 宽格式 | 交叉频次统计 |

经验:生成“行×列”二维汇总统首选 pivot_table;仅单列分组用 groupby 更简洁;问卷交叉分析用 crosstab。




综合实战:电商订单分析

模拟 200 条订单数据,按地区+季度为行、产品类别为列,销售额求和、利润求均值,并添加总计:
  1. import pandas as pd
  2. import numpy as np
  3. np.random.seed(42)
  4. n = 200
  5. df = pd.DataFrame({
  6.     '地区': np.random.choice(['华东', '华北', '华南', '西部'], n),
  7.     '产品类别': np.random.choice(['电子', '服装', '食品'], n),
  8.     '季度': np.random.choice([1, 2, 3, 4], n),
  9.     '销售额': np.random.randint(1000, 50000, n),
  10.     '利润': np.random.randint(100, 10000, n),
  11.     '订单数': np.random.randint(1, 100, n)
  12. })
  13. pivot = pd.pivot_table(
  14.     data=df,
  15.     values=['销售额', '利润'],
  16.     index=['地区', '季度'],
  17.     columns='产品类别',
  18.     aggfunc={'销售额': 'sum', '利润': 'mean'},
  19.     fill_value=0,
  20.     margins=True,
  21.     margins_name='汇总'
  22. )
  23. # 扁平化列名
  24. pivot.columns = ['_'.join(col) for col in pivot.columns]
  25. print(pivot.head(10))
  26. # 单独看华东的数据
  27. print(pivot.xs('华东', level='地区'))
复制代码




总结

pivot_table 将分组、聚合、重塑压缩为声明式代码。核心习惯:用 index/columns 控制维度,aggfunc 字典处理异构聚合,margins=True 自动加总计,fill_value 填充空缺,结果是标准 DataFrame 可继续链式操作。多跑真实数据,很快就能掌握。
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Pandas pivot_table 从参数到电商实战:聚合与多维透视完全指南

楼主整理得很详细,从参数到场景实战都很清晰,尤其是对不同列使用不同聚合函数那段,之前一直没注意到 `aggfunc` 传字典的写法,学到了。 想请教一个细节:在实际电商数据中,如果 `index` 和 `columns` 里都有很多分类字段(比如地区、品类、渠道),生成的透视表列数会爆炸,有没有什么方法在 `pivot_table` 之后快速筛选出需要的子表?目前我都是用 `xs` 或 `loc` 做切片,但多层索引切起来容易搞混。或者有没有更优雅的扁平化方式?感谢分享!
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Pandas pivot_table 从参数到电商实战:聚合与多维透视完全指南

写得非常详细,参数解释和场景示例都很清楚,特别是对不同列用不同聚合函数和实际销售报表的案例,特别实用。之前我每次用multi-level columns时都容易搞混,看了你的多层索引和xs切片那段,终于理清了。有个小问题想请教:在真实场景中,如果index和columns里都有缺失值,pivot_table默认会怎么处理?dropna=True是先剔除所有包含NaN的行再聚合吗?谢谢。
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Pandas pivot_table 从参数到电商实战:聚合与多维透视完全指南

感谢楼主的详细教程!之前用 pivot_table 经常记不清参数,你这篇把每个参数都拆开讲清楚,还配了电商实战例子,特别实用。我平时做销售报表时也喜欢用 margins 加总计,但有时对不同列选不同 aggfunc 会把多级列索引搞乱,你给的字典写法刚好解决了这个痛点。另外想请教一下,如果数据里 index 或 columns 的字段中有 NaN,fill_value 在聚合前和聚合后的处理顺序有没有什么坑?希望楼主再讲讲这个细节。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-3 13:05 , Processed in 0.035179 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部