Pandas数据透视表pivot_table的使用小结

 更新时间:2026年07月03日 09:13:17   作者:卷无止境  
本文主要介绍了Pandas数据透视表pivot_table的使用小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

数据分析师大概都有过这样的经历——面对一张几万行的原始数据表,老板要的是"按地区、按季度、按产品类别"的汇总报表,而你手里只有一堆散乱的流水记录。这时候,pivot_table 就是你最得力的工具。它不是什么高深的黑魔法,本质上就是把"长条形"的原始数据,折叠成一张人人看得懂的二维汇总表——同时完成分组、聚合、重塑三件事,一行代码搞定。

一、先搞清楚它在做什么

pivot_table 的工作逻辑,拆开来看其实只有三步:

第一步,分组。 按照你指定的 indexcolumns 字段,把数据切成若干个小格子——就像把一张大桌子划分成行和列的网格。

第二步,聚合。 每个格子里可能有多条记录,用 aggfunc 指定的函数(求和、均值、计数……)把它们压缩成一个数字。

第三步,重塑。 把压缩后的结果摆进二维表格,行由 index 决定,列由 columns 决定,一张干净的汇总表就成型了。

这里有个容易混淆的地方:pivot()pivot_table() 长得很像,但前者要求每个行列组合唯一,遇到重复数据直接报错;后者通过聚合函数处理重复值,日常工作中几乎永远用后者。同样,groupby() 也能分组聚合,但输出的是"长格式"结果,不会自动帮你铺成二维表。三者各有用武之地,但要生成报表,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,   # pandas 2.2+ 建议显式设为 True
    sort=True
)

参数不多,但每一个都有讲究,下面逐一说清楚:

参数类型默认值说明
dataDataFrame必填输入数据源
valuesstr / listNone要聚合的数值列;省略则对所有数值列聚合
indexstr / listNone行分组字段,传列表可形成多层索引
columnsstr / listNone列分组字段,传列表可形成多层列
aggfuncfunc / list / dict'mean'聚合函数,支持字符串、函数、列表、字典
fill_valuescalarNone聚合后产生的 NaN 用此值填充
marginsboolFalse是否在末尾添加行列汇总(小计/总计)
dropnaboolTrue聚合前是否丢弃全为 NaN 的列
margins_namestr'All'汇总行/列的标签,可改成"合计"或"总计"
observedboolFalse仅对 Categorical 类型有效,True 则只展示实际出现的值
sortboolTrue结果是否排序(v1.3.0 新增)

有两个参数特别容易被忽略,单独说一下。

fill_valuedropna 经常被当成同一回事,但它们作用的时机完全不同。dropna=True 发生在聚合之前,把含 NaN 的行直接丢掉;fill_value 发生在聚合之后,把结果表里出现的空格填上指定的值。两者同时使用时,先丢后填,顺序不能搞反。

observed 参数在 pandas 2.2 之后变得重要起来。如果分组字段是 Categorical 类型,默认的 observed=False 会把所有类别组合都列出来,哪怕某些组合在数据里根本不存在,结果表会凭空多出一堆全零的行。改成 observed=True 就只展示真实出现过的组合,干净很多。

三、从零开始,跑通第一个例子

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": [1, 2, 2, 3, 3, 4, 5, 6, 7],
    "E": [2, 4, 5, 5, 6, 6, 8, 9, 9]
})

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

table = pd.pivot_table(df, values='D', index=['A', 'B'],
                       columns=['C'], aggfunc="sum")
# C        large  small
# A   B
# bar one    4.0    5.0
#     two    7.0    6.0
# foo one    4.0    1.0
#     two    NaN    6.0

结果里出现了 NaN——因为 foo/two/large 这个组合在原始数据里不存在。加上 fill_value=0 就能填平:

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

对不同列用不同聚合函数: 这是 aggfunc 字典语法最实用的地方——D 列求均值,E 列同时算最小值、最大值和均值。

table = pd.pivot_table(df, values=['D', 'E'], index=['A', 'C'],
                       aggfunc={'D': 'mean', 'E': ['min', 'max', 'mean']})
# 结果列变成多层,E 列下挂三个子列

四、真实场景里怎么用

销售报表:最经典的用法

季度销售汇总大概是 pivot_table 被用得最多的场景。一张原始订单表,几行代码变成管理层要的那种"行是季度、列是地区、格子里是销售额"的报表:

data = {
    '地区': ['华东', '华东', '华北', '华北', '华南', '华南'],
    '产品': ['A', 'B', 'A', 'B', 'A', 'B'],
    '季度': [1, 1, 1, 2, 2, 2],
    '销售额': [150000, 120000, 90000, 110000, 130000, 95000],
    '利润':  [30000,  24000,  18000,  22000,  26000,  19000]
}
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)

margins=True 会自动在末尾追加一行一列的汇总,省去手动求和的麻烦。

时间维度分析:多层索引的威力

当你想同时按"地区"和"月份"分行时,把它们打包成列表传给 index 就行,pandas 会自动生成多层索引:

df['月份'] = df['日期'].dt.month

pivot = pd.pivot_table(
    data=df,
    index=['地区', '月份'],   # 两级行索引
    columns='产品',
    values='销售额',
    aggfunc='sum'
)

生成的表格可以用 .xs() 切片访问某一层:

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

用户行为分析:多函数同时上

想同时看"总访问量"和"人均访问次数"?一次搞定:

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

五、几个让结果更好用的技巧

自定义聚合函数

aggfunc 接受任意 Python 函数,不局限于内置统计量。比如想算极差(最大值减最小值):

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,导出 Excel 或做后续处理时很麻烦。一行代码压平:

pivot.columns = ['_'.join(col).strip() for col in pivot.columns.values]
# 原来的 ('sum', 'D') 变成 'sum_D',清爽很多

链式操作:透视完接着筛选

pivot_table 的结果是标准 DataFrame,可以直接接 query()sort_values() 等操作:

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 最顺手。

七、综合实战:电商订单分析

把前面说的技巧都用上,跑一个完整的例子:

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([1, 2, 3, 4], 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,随时可以接后续操作。

剩下的,就是多跑几次真实数据,感觉自然就来了。

参考资料

  • pandas 官方 API 文档:pandas.pivot_table
  • pandas 官方用户指南:Reshaping and pivot tables
  • 华为云开发者社区:深入探究Pandas中的透视表:基础到高级应用全覆盖
  • 百度 Comate:Pandas数据透视表:多维度聚合与动态分析实战指南

到此这篇关于Pandas数据透视表pivot_table的使用小结的文章就介绍到这了,更多相关Pandas数据透视表pivot_table内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • django xadmin action兼容自定义model权限教程

    django xadmin action兼容自定义model权限教程

    这篇文章主要介绍了django xadmin action兼容自定义model权限教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • 跟老齐学Python之模块的加载

    跟老齐学Python之模块的加载

    这篇文章主要介绍了跟老齐学Python之模块的加载,需要的朋友可以参考下
    2014-10-10
  • 使用Python Matplotlib处理地理数据可视化

    使用Python Matplotlib处理地理数据可视化

    地理数据可视化是数据科学中一个重要的领域,它帮助我们理解和分析与地理位置相关的数据,Python 提供了强大的工具来处理地理数据,本文将介绍如何使用 Python Matplotlib 处理地理数据可视化,包括基础概念、常用库、数据处理以及实际案例,需要的朋友可以参考下
    2024-11-11
  • 图文详解Python中最神秘的一个魔法函数

    图文详解Python中最神秘的一个魔法函数

    Python进阶之路我觉得有两个东西一定要了解,一个是魔法函数,下面这篇文章主要给大家介绍了关于Python中最神秘的一个魔法函数的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2021-12-12
  • python获取文件后缀名及批量更新目录下文件后缀名的方法

    python获取文件后缀名及批量更新目录下文件后缀名的方法

    这篇文章主要介绍了python获取文件后缀名及批量更新目录下文件后缀名的方法,实例展示了Python针对文件后缀名的遍历查找及修改等常用操作技巧,并对其中的关键知识点进行了分析与总结,需要的朋友可以参考下
    2014-11-11
  • django_orm查询性能优化方法

    django_orm查询性能优化方法

    这篇文章主要介绍了django_orm查询性能优化方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 超级详细实用的pycharm常用快捷键

    超级详细实用的pycharm常用快捷键

    本文详细总结了Pycharm的常用快捷键,下文介绍使用方法和场景, 并不需要记忆这些快捷键, 你只需要知道有这些快捷键, 再需要用的时候查看一下, 用的多了自然也就记住了,需要的朋友可以参考下
    2021-05-05
  • Python中列表元素转为数字的方法分析

    Python中列表元素转为数字的方法分析

    这篇文章主要介绍了Python中列表元素转为数字的方法,结合实例形式对比分析了Python列表操作及数学运算的相关技巧,需要的朋友可以参考下
    2016-06-06
  • Numpy ndarray 多维数组对象的使用

    Numpy ndarray 多维数组对象的使用

    这篇文章主要介绍了Numpy ndarray 多维数组对象的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • Python数据可视化之Pandas、Matplotlib与Seaborn的高效实战指南

    Python数据可视化之Pandas、Matplotlib与Seaborn的高效实战指南

    本文介绍了Python数据可视化的综合解决方案,涵盖Pandas、Matplotlib和Seaborn三大工具的使用技巧,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
    2026-02-02

最新评论