news 2026/10/13 7:08:45

Python制作数据分析透视表的方法详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python制作数据分析透视表的方法详解

前言


透视表(pivot table)是把"长表"转成"交叉表"的经典操作: 用一列做行标签、一列做列标签、一列做取值,交叉的格子里放聚合结果。 Excel 里的透视表人人会点,pandas 里对应的是pivot_table。


初学者最容易犯的两个错:一是把pivot和pivot_table当成一回事; 二是以为不传聚合函数就是求和。实际情况是:pivot只做重塑、不聚合, 遇到重复的"行×列"组合会直接报错;而pivot_table默认的聚合函数是平均值"mean",不是求和。


需要说明:pandas 是第三方库,本机没有 Python 解释器也没有 pandas, 示例无法运行验证,只能逐行人工推演。参数细节以 Pandas 官方文档为准。


一、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=True,
sort=True, **kwargs)



参数作用



data输入DataFrame

values要聚合的数值列

index放到行上的分组键

columns放到列上的分组键

aggfunc聚合函数,默认"mean"

fill_value结果里缺失填什么

margins是否加合计行列



理解方式:index和columns是分组维度,values是被聚合的度量,aggfunc决定怎么聚。它和groupby是一体的——pivot_table基本可以理解为 "按index和columns分组后,对values做aggfunc,再把结果摊开"。 参数里dropna=True指的是分组键含缺失的行会被丢弃, 和后面讲的"结果表里的空位"不是一回事,别混淆。


二、最基础的例子


# pandas 1.0+
import pandas as pd

df = pd.DataFrame(
{
"region": ["东", "东", "南", "南", "东"],
"month": ["1月", "2月", "1月", "2月", "1月"],
"amount": [10, 20, 30, 40, 50],
}
)

table = pd.pivot_table(
df,
values="amount",
index="region",
columns="month",
aggfunc="sum",
fill_value=0,
margins=True, # 加 All 合计行列
)
print(table)

注意这里显式写了aggfunc="sum"。如果不写,结果会是均值, 这是与直觉最不一致的地方,务必记住。


三、多个聚合函数、多列取值


aggfunc可以传列表,values也可以传列表:


# pandas 1.0+
table = pd.pivot_table(
df,
values="amount",
index="region",
columns="month",
aggfunc=["sum", "count"],
)

这样会产生"外层是聚合函数、内层是月份"的列层级(MultiIndex的列)。 当values和aggfunc都是列表时,列层级会更多一层, 取值时要用元组逐级定位,例如table[("sum", "1月")]。


四、fill_value 与 margins



  • fill_value填的是结果表里的空位。因为不是每种"维度组合"都有数据,


交叉后必然出现空格,填 0 或填其他默认值能让表更整齐。



  • margins=True会增加All行和All列,值是对应的汇总。


汇总用的函数由aggfunc决定;多函数时行为要按文档确认。



  • margins_name可改合计行列的名字,默认是"All"。


五、pivot 与 pivot_table 的区别




对比pivotpivot_table



是否聚合不聚合,只重塑会聚合

重复组合报错用aggfunc合并

默认聚合无"mean"

适用已经是唯一组合的整洁数据有重复、需要汇总的数据



pivot的语义很直接:index+columns必须唯一确定一个values, 否则就抛出ValueError: Index contains duplicate entries。 遇到这个报错,第一反应应该是改用pivot_table并指定aggfunc。


六、crosstab:另一条做交叉表的路


如果只是想数"两个类别交叉出现多少次",pd.crosstab更顺手:


# pandas 1.0+
freq = pd.crosstab(df["region"], df["month"])
print(freq)

crosstab默认做的是计数(频数),它接受的是类别的序列而不是整张表, 语义上和透视表互补。它还支持normalize参数,用来把频数换算成比例或百分比 (例如按行、按列或整体归一),做占比分析时很方便。


七、把结果整理成"平表"


透视表的结果通常带着行索引和列索引(可能是多层),直接写 Excel 会挤在一起, 不适合再加工。常见的整理方式是"压平列名 + 重置索引":


# pandas 1.0+
flat = table.reset_index()
flat.columns = ["_".join(map(str, col)) if isinstance(col, tuple) else str(col)
for col in flat.columns]
print(flat)

reset_index()把行索引变回普通列,列名若是多层元组就拼成一个字符串, 得到的就是一张规规矩矩的平表,可以直接交给to_excel或下游系统。


如果只是想快速看结构,table.stack()/table.unstack()能在 "宽表"和"长表"之间切换;但stack后缺失值默认会被丢掉, 需要保留请显式传dropna=False。


八、完整示例


# pandas 1.0+
import pandas as pd


def report(rows: pd.DataFrame) -> pd.DataFrame:
table = pd.pivot_table(
rows,
values="amount",
index="region",
columns="month",
aggfunc="sum",
fill_value=0,
margins=True,
margins_name="合计",
)
return table.sort_values("合计", ascending=False)


if __name__ == "__main__":
data = pd.DataFrame(
{
"region": ["东", "南", "东"],
"month": ["1月", "1月", "2月"],
"amount": [10, 30, 20],
}
)
print(report(data))

常见坑点



  1. 以为pivot_table默认求和


❌ 不写aggfunc直接调用,得到的是平均值,和报表预期不符 ✅ 求和就写aggfunc="sum",求计数写"count"或"size"



  1. 用pivot处理有重复组合的数据


❌df.pivot(index="a", columns="b", values="c"),抛"重复条目"错误 ✅ 改pivot_table(..., aggfunc="sum")让重复组合被聚合掉



  1. 用==之类的判等去找透视表里的空值


❌ 结果表里的空位当成普通缺失用==比,比不出来 ✅ 生成时就传fill_value=0,或事后用isna()判定



  1. fill_value和原始数据的填充搞混


❌ 以为fill_value会改原始DataFrame✅fill_value只作用于生成的透视表,原表不变



  1. 多函数聚合后按列名直接取列


❌table["1月"]报 KeyError,因为列已经变成多层索引 ✅ 用元组定位table[("sum", "1月")],或先table.columns看层级



  1. aggfunc="count"与"size"混用


❌ 想数行数却用"count",结果NaN没被算进去,数目偏小 ✅"count"数非缺失值,"size"数行数(含缺失),按需求选



  1. 分组维度里有分类类型时列爆炸


❌ 某个键是category类型且基数很大,透视表出几百列且大量为空 ✅ 注意observed参数:为True时只显示出现过的组合,避免空组合撑爆列


总结




需求该怎么做



交叉汇总pivot_table(values=, index=, columns=, aggfunc=)

默认行为aggfunc是"mean",不是"sum"

填空白fill_value=

加合计margins=True

只重塑不聚合pivot(要求组合唯一)

只数频数pd.crosstab



透视表的本质是"分组 + 摊开"。只要记住index/columns是维度、values是度量、aggfunc默认是均值,绝大多数困惑都能避免。 真正动手前,建议先在数据上跑一次groupby确认口径,再换pivot_table摊平。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 7:08:30

工业互联网技术体系拆解:三层架构、避坑与落地实战

简介:面向工业互联网与智能制造初学者的一份体系化PPT课件,定位为工业互联网技术体系的入门与概览材料。课件以制造技术、信息技术、融合技术为主线,系统梳理了工业App低代码开发、安全技术、工业大数据处理与管理、数字孪生、感知与工业视觉…

作者头像 李华
网站建设 2026/10/13 7:08:22

IntelliJ IDEA Debug 高阶技巧:断点、多线程与远程调试实战

简介:这份PDF资料聚焦IntelliJ IDEA的Debug调试技巧,面向Java后端开发、Web工程调试人员及需要提升排错效率的初中级开发者。内容以实际Web工程为例,系统梳理断点设置、Debug模式启动、单步执行、查看变量值、跳过方法与重新开始执行等核心操…

作者头像 李华
网站建设 2026/10/13 7:08:14

告别20个终端:cmux为AI编程搭建统一作战台

我最近小半年基本泡在 AI 编程工作流里:让 Agent 改代码、跑单测、起服务、看页面,再把报错丢回去让它继续修。听起来很顺,但真正让我抓狂的不是 Agent 智商不够,而是我的终端工作台彻底失控——一个窗口跑 Agent 的流式输出&…

作者头像 李华
网站建设 2026/10/13 7:07:42

FT6336触控驱动调试:从I²C初始化到Linux input子系统落地

简介:本资源为嵌入式Linux平台下FT6336电容式触摸控制器的完整I2C驱动源码包,面向嵌入式驱动开发工程师、Linux内核初学者及智能终端硬件适配人员,解决触控设备在定制化板卡上的功能接入与调试问题。压缩包共5个文件(2个头文件.h、…

作者头像 李华
网站建设 2026/10/13 7:07:27

机器灵巧手核心技术解析:触觉-视觉-运动毫秒级闭环实现路径

1. 项目概述:这不是“机械手”,而是“灵巧手”——从OpenAI实验室那张引发全网热议的动图说起你肯定见过那张图:一只银灰色、关节分明的机械结构,正用拇指和食指稳稳捏起一枚薄如蝉翼的薯片,指尖微微施力,薯…

作者头像 李华
网站建设 2026/10/13 7:06:45

独立开发APP技术栈选型实战:从Flutter到自建后端的完整决策链

1. 技术栈选型:从零到发布,为什么这一步决定了后面80%的坑做独立开发最怕什么?不是代码写不出来,而是写到一半发现选错了技术栈,推倒重来的成本高到让人想放弃。我见过太多人,第一行代码还没敲,…

作者头像 李华