脚本专家 发表于 2026-7-3 10:00:04

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

数据分析中,面对原始流水数据,需要按多个维度分组汇总出二维报表。Pandas 的 pivot_table 能将分组、聚合、重塑三步合并为一行代码,是生成报表的最直接工具。本文从参数详解、基础示例、真实场景、横向对比到综合实战,完整演示 pivot_table 的核心用法。



核心参数说明

pivot_table 的签名为:


pandas.pivot_table(
    data,
    values=None,
    index=None,
    columns=None,
    aggfunc='mean',
    fill_value=None,
    margins=False,
    dropna=True,
    margins_name='All',
    observed=False,
    sort=True
)


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

- 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 新增)。



基础用法演示

先准备示例数据:


import pandas as pd
import numpy as np

df = pd.DataFrame({
    "A": ["foo", "foo", "foo", "foo", "foo", "bar", "bar", "bar", "bar"],
    "B": ["one", "one", "one", "two", "two", "one", "one", "two", "two"],
    "C": ["small", "large", "large", "small", "small", "large", "small", "small", "large"],
    "D": ,
    "E":
})


最基础用法:按 A、B 分行,按 C 分列,对 D 列求和:


table = pd.pivot_table(df, values='D', index=['A', 'B'],
                     columns=['C'], aggfunc="sum", fill_value=0)
print(table)


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

对不同列使用不同聚合函数:


table = pd.pivot_table(df, values=['D', 'E'], index=['A', 'C'],
                     aggfunc={'D': 'mean', 'E': ['min', 'max', 'mean']})
print(table)


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



真实场景实战

1. 销售报表

按季度和地区汇总销售额与利润:


data = {
    '地区': ['华东', '华东', '华北', '华北', '华南', '华南'],
    '产品': ['A', 'B', 'A', 'B', 'A', 'B'],
    '季度': ,
    '销售额': ,
    '利润':
}
df_sales = pd.DataFrame(data)
pivot = pd.pivot_table(
    data=df_sales,
    values=['销售额', '利润'],
    index='季度',
    columns='地区',
    aggfunc='sum',
    fill_value=0,
    margins=True,
    margins_name='总计'
)
print(pivot)


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

将“地区”和“月份”作为行索引,产品作为列:


df['月份'] = df['日期'].dt.month
pivot = pd.pivot_table(
    data=df,
    index=['地区', '月份'],
    columns='产品',
    values='销售额',
    aggfunc='sum'
)
# 用 xs 切片
print(pivot.xs('华东', level='地区'))


3. 用户行为多函数聚合

同时查看总访问量和人均次数:


pivot = pd.pivot_table(
    data=df_user,
    index='用户等级',
    columns='访问渠道',
    values='访问次数',
    aggfunc=['sum', 'mean'],
    fill_value=0
)




高级技巧

自定义聚合函数:用 lambda 计算极差(最大值减最小值):


pivot = pd.pivot_table(df, values='D', index='A',
                     aggfunc=lambda x: x.max() - x.min())


同时使用多个内置函数:


pivot = pd.pivot_table(df, values='D', index='A',
                     aggfunc=['sum', 'mean', 'count', np.std])


扁平化多层列名:当 aggfunc 为列表/字典时,列索引变为 MultiIndex,可用列表推导压平:


pivot.columns = ['_'.join(col).strip() for col in pivot.columns.values]


链式操作:透视结果是标准 DataFrame,可直接接 reset_index、sort_values、query:


result = (
    pd.pivot_table(df, values='销售额', index='地区', aggfunc='sum')
    .reset_index()
    .sort_values('销售额', ascending=False)
    .query('销售额 > 100000')
)




相近方法对比

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

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



综合实战:电商订单分析

模拟 200 条订单数据,按地区+季度为行、产品类别为列,销售额求和、利润求均值,并添加总计:


import pandas as pd
import numpy as np

np.random.seed(42)
n = 200
df = pd.DataFrame({
    '地区': np.random.choice(['华东', '华北', '华南', '西部'], n),
    '产品类别': np.random.choice(['电子', '服装', '食品'], n),
    '季度': np.random.choice(, n),
    '销售额': np.random.randint(1000, 50000, n),
    '利润': np.random.randint(100, 10000, n),
    '订单数': np.random.randint(1, 100, n)
})

pivot = pd.pivot_table(
    data=df,
    values=['销售额', '利润'],
    index=['地区', '季度'],
    columns='产品类别',
    aggfunc={'销售额': 'sum', '利润': 'mean'},
    fill_value=0,
    margins=True,
    margins_name='汇总'
)

# 扁平化列名
pivot.columns = ['_'.join(col) for col in pivot.columns]
print(pivot.head(10))

# 单独看华东的数据
print(pivot.xs('华东', level='地区'))




总结

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

热心网友1 发表于 2026-7-3 10:10:00

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

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

热心网友1 发表于 2026-7-3 10:10:00

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

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

热心网友1 发表于 2026-7-3 10:10:00

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

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