13. Pandas 透视表与交叉表分析
Pandas 透视表与交叉表分析
在数据分析中,我们常常需要对数据进行多维汇总与分类统计,以发现趋势、比较差异或生成业务报表。Pandas 提供的 pivot_table
(透视表)与 crosstab
(交叉表)函数,正是实现这一目标的高效工具。透视表更灵活,支持多层聚合与缺失值处理,而交叉表则更适合做类别变量之间的统计分析。
1. 透视表(pivot_table)
pivot_table
能够根据指定的行、列维度对数据进行汇总,并应用聚合函数,是 Excel 数据透视表在 Python 中的强大替代方案。
import pandas as pddata = {"姓名": ["张三", "李四", "王五", "赵六", "孙七", "周八"],"城市": ["北京", "上海", "北京", "深圳", "上海", "北京"],"部门": ["A", "B", "A", "B", "A", "B"],"销售额": [100, 150, 200, 130, 160, 180]
}
df = pd.DataFrame(data)
print(df)
姓名 城市 部门 销售额
0 张三 北京 A 100
1 李四 上海 B 150
2 王五 北京 A 200
3 赵六 深圳 B 130
4 孙七 上海 A 160
5 周八 北京 B 180
1.1 基础透视表
例如,按“城市”维度汇总销售额总和:
pivot_city = df.pivot_table(values='销售额', index='城市', aggfunc='sum')
print(pivot_city)
销售额
城市
上海 310
北京 480
深圳 130
这一步相当于执行了按城市分组求和的操作,但透视表输出结构更清晰、更直观。
1.2 多维透视表
当分析需要同时考虑多个维度时,可以同时指定 index
(行)、columns
(列)和 aggfunc
(聚合函数)。例如按“城市”和“部门”统计销售额:
pivot_multi = df.pivot_table(values='销售额',index='城市',columns='部门',aggfunc='sum',fill_value=0 # 缺失值填充为 0
)
print(pivot_multi)
部门 A B
城市
上海 160 150
北京 300 180
深圳 0 130
多维透视表非常适合用于比较不同地区、部门、时间段等多个维度下的业务表现。
2. 交叉表(crosstab)
crosstab
更偏向于分析分类变量之间的关系,能够快速生成频次分布或带聚合值的交叉统计表。
2.1 分类频次统计
cross_tab = pd.crosstab(df['城市'], df['部门'])
print(cross_tab)
部门 A B
城市
上海 1 1
北京 2 1
深圳 0 1
该表展示了各城市中不同部门的人数分布,是类别变量交叉分析中最常见的形式。
2.2 带聚合值的交叉表
crosstab
还可以结合 values
与 aggfunc
参数,计算数值型变量的聚合结果。例如统计每个城市和部门的销售额总和:
cross_tab_sales = pd.crosstab(df['城市'], df['部门'],values=df['销售额'],aggfunc='sum',dropna=False
).fillna(0)print(cross_tab_sales)
部门 A B
城市
上海 160.0 150.0
北京 300.0 180.0
深圳 0.0 130.0
crosstab
的语法简洁,适合快速生成频次表或分组汇总结果。
3. 进阶应用
3.1 计算透视表中各项占比
在业务分析中,我们往往不仅关心总额,还关心各城市或部门的相对占比。可以通过除以行总和的方式直接实现:
pivot_share = pivot_multi.div(pivot_multi.sum(axis=1), axis=0).round(2)
print("各城市销售额占比:\n", pivot_share)
各城市销售额占比:部门 A B
城市
上海 0.52 0.48
北京 0.62 0.38
深圳 0.00 1.00
这样可以快速得出结构性分析结果,如不同部门在各城市的销售比例。
3.2 在交叉表中添加总计行与总计列
交叉表默认不会自动添加合计项,但可以通过设置 margins=True
实现:
cross_tab_total = pd.crosstab(df['城市'], df['部门'], margins=True, margins_name='总计')
print(cross_tab_total)
部门 A B 总计
城市
上海 1 1 2
北京 2 1 3
深圳 0 1 1
总计 3 3 6
这在生成业务报表或统计总览时非常实用,尤其是配合可视化输出时效果更佳。
4.可视化拓展
数据汇总的最终目的往往是可视化展示。透视表和交叉表生成的数据结构天然适合直接绘图,例如条形图、堆叠图或热力图。
4.1 绘制透视表的条形图
import matplotlib.pyplot as plt
import seaborn as snssns.set_theme(style="whitegrid", font="SimHei", rc={"axes.unicode_minus": False})pivot_multi.plot(kind='bar', figsize=(6, 4))
plt.title("各城市各部门销售额对比")
plt.ylabel("销售额")
plt.xlabel("城市")
plt.tight_layout()
plt.show()
这段代码会生成一个分组条形图,清晰展示不同城市、部门间的销售对比。
4.2 绘制交叉表的热力图
plt.figure(figsize=(5, 4))
sns.heatmap(cross_tab_sales,annot=True, # 显示数字fmt=".0f", # 不要科学计数,整数显示cmap='YlOrBr'
)
plt.title("城市 × 部门 销售额热力图")
plt.show()
热力图能直观地显示出高低分布——颜色越深表示销售额越高,非常适合呈现交叉表聚合结果。
5. 总结
透视表(pivot_table
)与交叉表(crosstab
)是 Pandas 中实现多维统计与报表分析的核心工具。前者具有更高的灵活性,能够在多维度下进行聚合、结构化输出,并妥善处理缺失值,适用于复杂的汇总分析场景。后者则以简洁直观的语法见长,非常适合快速生成频次统计表或简易的聚合结果。
通过进阶操作,分析者不仅可以在表格中计算占比、添加行列合计,还能显著提升数据表的可读性与信息密度。此外,将透视结果进一步可视化,例如绘制条形图或热力图,也能让分析成果更直观地呈现。
掌握这些方法,可以让从原始数据到可视化报告的全过程更加高效流畅,使数据分析既精准又生动。