项目6 数据透视表与交叉分析
学习目标
- 理解数据透视表的概念和用途
- 掌握
pivot_table() 方法创建透视表
- 学会使用
crosstab() 制作交叉表
- 理解多级索引(MultiIndex)的结构
- 学会添加 margins 总计行/列
- 能够按地区和品类做透视分析
知识点讲解
1. 什么是数据透视表?
数据透视表就像Excel里的"透视表"功能,可以把一大堆数据按照不同的维度重新排列组合,快速看到汇总结果。比如你有几千条销售记录,想知道"每个地区每个品类的销售额是多少",用透视表几秒钟就能搞定。
2. pivot_table() 基本用法
# 基本语法
df.pivot_table(
values='销售额', # 要汇总的数值列
index='地区', # 行方向的分组字段
columns='品类', # 列方向的分组字段
aggfunc='sum' # 汇总方式:sum/mean/count等
)
3. 交叉表 crosstab()
交叉表专门用来统计频次,比如"每个地区各买了多少单",它默认做计数(count),也可以指定其他聚合方式。
pd.crosstab(
df['地区'],
df['品类'],
values=df['销售额'],
aggfunc='sum'
)
4. 多级索引 MultiIndex
当 index 或 columns 传入列表时,就会生成多级索引。比如 index=['地区','城市'] 会先按地区分组,再按城市分组。
5. margins 总计
加上 margins=True 参数,会自动在最下面和最右边加上"All"总计行和总计列,非常方便。
完整代码示例
import pandas as pd
import numpy as np
# ========== 1. 创建模拟超市销售数据 ==========
np.random.seed(42)
data = {
'订单号': [f'ORD{i:04d}' for i in range(1, 101)],
'日期': pd.date_range('2024-01-01', periods=100, freq='D'),
'地区': np.random.choice(['华东', '华南', '华北', '西南'], 100),
'城市': np.random.choice(['上海', '广州', '北京', '成都', '杭州', '深圳'], 100),
'品类': np.random.choice(['食品', '饮料', '日用品', '家电', '服装'], 100),
'销售额': np.random.randint(50, 2000, 100),
'数量': np.random.randint(1, 20, 100)
}
df = pd.DataFrame(data)
print("原始数据预览:")
print(df.head(10))
# ========== 2. 基础透视表:按地区汇总销售额 ==========
print("\n【按地区汇总销售额】")
pt1 = df.pivot_table(values='销售额', index='地区', aggfunc='sum')
print(pt1)
# ========== 3. 二维透视表:地区 × 品类 ==========
print("\n【地区 × 品类 销售额透视表】")
pt2 = df.pivot_table(values='销售额', index='地区', columns='品类', aggfunc='sum')
print(pt2)
# ========== 4. 添加总计行/列 ==========
print("\n【带总计的透视表】")
pt3 = df.pivot_table(
values='销售额',
index='地区',
columns='品类',
aggfunc='sum',
margins=True,
margins_name='总计'
)
print(pt3)
# ========== 5. 多级索引透视表 ==========
print("\n【多级索引:地区+城市 × 品类】")
pt4 = df.pivot_table(
values='销售额',
index=['地区', '城市'],
columns='品类',
aggfunc='sum',
fill_value=0
)
print(pt4.head(12))
# ========== 6. 多种聚合方式 ==========
print("\n【同时计算销售额的总和与平均】")
pt5 = df.pivot_table(
values='销售额',
index='地区',
aggfunc=['sum', 'mean', 'count']
)
print(pt5)
# ========== 7. 交叉表 crosstab ==========
print("\n【交叉表:地区 vs 品类(订单数量)】")
ct1 = pd.crosstab(df['地区'], df['品类'])
print(ct1)
print("\n【交叉表:地区 vs 品类(销售额汇总)】")
ct2 = pd.crosstab(
df['地区'],
df['品类'],
values=df['销售额'],
aggfunc='sum'
).fillna(0)
print(ct2)
# ========== 8. 归一化交叉表(占比) ==========
print("\n【交叉表占比:每个地区的品类销售占比】")
ct3 = pd.crosstab(df['地区'], df['品类'], normalize='index') * 100
print(ct3.round(2))
实操步骤
步骤1:打开 Jupyter Notebook,新建一个 Notebook 文件。
步骤2:运行上面的"创建模拟超市销售数据"代码块,生成 100 条销售记录。
步骤3:先做一个最简单的透视表:只按"地区"分组,汇总"销售额",观察结果。
步骤4:尝试二维透视表,把"品类"放到 columns 参数,看看表格变成什么样。
步骤5:加上 margins=True,检查最下面和最右边是否出现了"总计"。
步骤6:把 index 改成 ['地区','城市'] 列表,体验多级索引的效果。
步骤7:用 pd.crosstab() 做一个地区和品类的交叉表,对比 pivot_table 的结果。
步骤8:尝试 normalize='index',把交叉表变成百分比形式。
第1题
选择题
pivot_table() 中,aggfunc='sum' 表示什么?
答案解析
aggfunc=sum 表示对分组后的数值求总和。
第2题
选择题
在透视表中,index 参数控制的是?
答案解析
index 参数指定行方向的分组字段,会出现在表格最左边。
第3题
选择题
想要透视表自动显示"总计"行和"总计"列,应该使用哪个参数?
答案解析
margins=True 会在透视表底部和右侧添加总计。
第4题
选择题
pd.crosstab() 默认的聚合方式是什么?
答案解析
crosstab 默认统计出现的频次,即 count。
第5题
判断题
多级索引就是把多个字段同时放到 index 参数中,用列表传入。
答案解析
index=["地区","城市"] 会生成多级索引,先按地区分组,再按城市分组。
第6题
填空题
在 pivot_table 中,columns 参数对应的是表格的 ______ 方向。
答案解析
columns 参数控制表格的列方向分组。
第7题
判断题
fill_value=0 可以把透视表中的空值(NaN)替换成 0。
答案解析
fill_value 参数用于填充透视表中因某些组合不存在而产生的 NaN 值。
项目小结
本项目我们学习了数据透视表的核心技能:
pivot_table() 是 pandas 里的"Excel透视表",可以快速按维度汇总数据。
index 控制行分组,columns 控制列分组,values 指定要计算的数值列。
aggfunc 可以选择 sum、mean、count 等多种聚合方式。
margins=True 一键添加总计,非常方便。
- 多级索引让分组更精细,比如同时按地区和城市分组。
crosstab() 适合快速做频次统计和占比分析。
掌握透视表后,面对成千上万行数据,你也能在几秒钟内得到清晰的汇总报表!