Pandas pd.pivot_table() 函数
pd.pivot_table() 是 Pandas 库中用于创建数据透视表的函数。数据透视表是电子表格中的常用功能,可以对数据进行分组、聚合和重塑,便于从不同角度分析数据。
与 pd.crosstab() 相比,pivot_table() 更加强大,支持多种聚合函数、处理缺失值、以及更复杂的数据重塑。
单词释义: pivot_table 意为"透视表",是一种可以动态改变数据布局的表格,可以从多个维度对数据进行汇总分析。
基本语法与参数
pd.pivot_table() 是 Pandas 库的顶级函数,用于创建数据透视表。
语法格式
pd.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')
参数说明
- 参数:
data- 类型: DataFrame。
- 描述: 源数据 DataFrame。
- 参数:
values- 类型: 列名或列名列表。
- 描述: 要聚合的列。如果不指定,会对所有数值列进行聚合。
- 参数:
index- 类型: 列名、列名列表或函数。
- 描述: 用作行索引的列。可以是单个列或多个列(列表),多个列会创建层次化索引。
- 参数:
columns- 类型: 列名或列名列表。
- 描述: 用作列索引的列。
- 参数:
aggfunc- 类型: 函数、字符串或函数列表。
- 描述: 聚合函数。常用值包括 'sum'、'mean'、'count'、'min'、'max'、'median'、'std' 等。默认是 'mean'。
- 参数:
fill_value- 类型: 标量或 None。
- 描述: 用于填充缺失值的数值。
- 参数:
margins- 类型: 布尔值。
- 描述: 是否添加行列合计。默认为
False。
函数说明
- 返回值: 返回一个 DataFrame,即数据透视表。
- 效果: 根据指定的行、列和聚合函数,对数据进行重塑和汇总。
实例
让我们通过一系列从简单到复杂的例子,彻底掌握 pd.pivot_table() 的用法。
示例 1:基础用法 - 创建简单透视表
实例
import pandas as pd
import numpy as np
# 1. 创建销售数据
sales = pd.DataFrame({
'date': pd.date_range('2023-01-01', periods=12, freq='D'),
'product': ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],
'region': ['North', 'North', 'North', 'South', 'South', 'South', 'East', 'East', 'East', 'West', 'West', 'West'],
'sales': [100, 150, 200, 180, 170, 160, 190, 200, 210, 220, 230, 240]
})
print("=== 销售数据 ===")
print(sales)
# 2. 创建透视表 - 按产品和地区汇总销售额
pivot = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='sum')
print("n=== pd.pivot_table() 销售透视表 ===")
print(pivot)
# 3. 使用 fill_value 填充缺失值
print("n=== 填充缺失值 (fill_value=0) ===")
pivot_fill = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='sum', fill_value=0)
print(pivot_fill)
import numpy as np
# 1. 创建销售数据
sales = pd.DataFrame({
'date': pd.date_range('2023-01-01', periods=12, freq='D'),
'product': ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],
'region': ['North', 'North', 'North', 'South', 'South', 'South', 'East', 'East', 'East', 'West', 'West', 'West'],
'sales': [100, 150, 200, 180, 170, 160, 190, 200, 210, 220, 230, 240]
})
print("=== 销售数据 ===")
print(sales)
# 2. 创建透视表 - 按产品和地区汇总销售额
pivot = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='sum')
print("n=== pd.pivot_table() 销售透视表 ===")
print(pivot)
# 3. 使用 fill_value 填充缺失值
print("n=== 填充缺失值 (fill_value=0) ===")
pivot_fill = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='sum', fill_value=0)
print(pivot_fill)
运行结果预期:
=== 销售数据 ===
date product region sales
0 2023-01-01 A North 100
1 2023-01-01 B North 150
2 2023-01-01 C North 200
3 2023-01-01 A South 180
4 2023-01-01 B South 170
5 2023-01-01 C South 160
6 2023-01-01 A East 190
7 2023-01-01 B East 200
8 2023-01-01 C East 210
9 2023-01-01 A West 220
10 2023-01-01 B West 230
11 2023-01-01 C West 240
=== pd.pivot_table() 销售透视表 ===
region East North South West
product
A 400.0 100.0 180.0 220.0
B 400.0 150.0 170.0 230.0
C 410.0 200.0 160.0 240.0
=== 填充缺失值 (fill_value=0) ===
region East North South West
product
A 400 100 180 220
B 400 150 170 230
C 410 200 160 240
代码解析:
- 透视表按产品(行)和地区(列)汇总销售额。
fill_value=0将缺失的组合显示为 0,便于阅读。
示例 2:使用不同的聚合函数
aggfunc 参数可以指定多种聚合方式来分析数据。
实例
import pandas as pd
import numpy as np
# 1. 创建更丰富的销售数据
sales = pd.DataFrame({
'product': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'],
'region': ['North', 'North', 'South', 'South', 'East', 'East', 'West', 'West', 'North', 'South'],
'sales': [100, 150, 200, 180, 190, 200, 220, 230, 110, 190],
'quantity': [10, 15, 20, 18, 19, 20, 22, 23, 11, 19]
})
print("=== 销售数据 ===")
print(sales)
# 2. 汇总(求和)
print("n=== 销售额求和 ===")
sum_result = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='sum')
print(sum_result)
# 3. 计算平均销售额
print("n=== 销售额平均值 ===")
mean_result = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='mean')
print(mean_result.round(1))
# 4. 同时计算多种统计量(传递列表)
print("n=== 同时计算数量和、均值 ===")
multi_agg = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc=['sum', 'mean'])
print(multi_agg)
import numpy as np
# 1. 创建更丰富的销售数据
sales = pd.DataFrame({
'product': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'],
'region': ['North', 'North', 'South', 'South', 'East', 'East', 'West', 'West', 'North', 'South'],
'sales': [100, 150, 200, 180, 190, 200, 220, 230, 110, 190],
'quantity': [10, 15, 20, 18, 19, 20, 22, 23, 11, 19]
})
print("=== 销售数据 ===")
print(sales)
# 2. 汇总(求和)
print("n=== 销售额求和 ===")
sum_result = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='sum')
print(sum_result)
# 3. 计算平均销售额
print("n=== 销售额平均值 ===")
mean_result = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='mean')
print(mean_result.round(1))
# 4. 同时计算多种统计量(传递列表)
print("n=== 同时计算数量和、均值 ===")
multi_agg = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc=['sum', 'mean'])
print(multi_agg)
运行结果预期:
=== 销售数据 ===
product region sales quantity
0 A North 100 10
1 B North 150 15
2 A South 200 20
3 B South 180 18
4 A East 190 19
5 B East 200 20
6 A West 220 22
7 B West 230 23
8 A North 110 11
9 B South 190 19
=== 销售额求和 ===
region East North South West
product
A 190 210 200 220
B 200 150 370 230
=== 销售额平均值 ===
region East North South West
product
A 190 105.0 200 220
B 200 150.0 185 230
=== 同时计算数量和、均值 ===
sum mean
region East North South West East North South West
product
A 190 210 200 220 190 105.0 200 220
B 200 150 370 230 200 150.0 185.0 230
代码解析:
- 使用不同的聚合函数可以计算不同的统计指标。
- 同时传递多个聚合函数时,透视表会创建多层列索引。
示例 3:使用 margins 添加合计
使用 margins 参数可以添加行列合计,便于查看汇总数据。
实例
import pandas as pd
# 使用之前的销售数据
sales = pd.DataFrame({
'product': ['A', 'B', 'A', 'B', 'A', 'B'],
'region': ['North', 'North', 'South', 'South', 'East', 'East'],
'sales': [100, 150, 200, 180, 190, 200]
})
# 1. 无合计
print("=== 无合计 ===")
print(pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='sum'))
# 2. 添加行列合计
print("n=== 添加合计 (margins=True) ===")
result = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='sum', margins=True)
print(result)
# 3. 自定义合计名称
print("n=== 自定义合计名称 ===")
result_name = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='sum', margins=True, margins_name='总计')
print(result_name)
# 4. 多层行索引的合计
print("n=== 多层行索引 ===")
multi_index = pd.pivot_table(sales, values='sales', index=['product', 'region'], aggfunc='sum')
print(multi_index)
# 使用之前的销售数据
sales = pd.DataFrame({
'product': ['A', 'B', 'A', 'B', 'A', 'B'],
'region': ['North', 'North', 'South', 'South', 'East', 'East'],
'sales': [100, 150, 200, 180, 190, 200]
})
# 1. 无合计
print("=== 无合计 ===")
print(pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='sum'))
# 2. 添加行列合计
print("n=== 添加合计 (margins=True) ===")
result = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='sum', margins=True)
print(result)
# 3. 自定义合计名称
print("n=== 自定义合计名称 ===")
result_name = pd.pivot_table(sales, values='sales', index='product', columns='region', aggfunc='sum', margins=True, margins_name='总计')
print(result_name)
# 4. 多层行索引的合计
print("n=== 多层行索引 ===")
multi_index = pd.pivot_table(sales, values='sales', index=['product', 'region'], aggfunc='sum')
print(multi_index)
运行结果预期:
=== 无合计 ===
region East North South
product
A 190 100 200
B 200 150 180
=== 添加合计 (margins=True) ===
region East North South All
product
A 190 100 200 490
B 200 150 180 530
All 390 250 380 1020
=== 自定义合计名称 ===
region East North South 总计
product
A 190 100 200 490
B 200 150 180 530
总计 390 250 380 1020
=== 多层行索引 ===
sales
product region
A East 190
North 100
South 200
B East 200
North 150
South 180
代码解析:
margins=True会添加 "All" 行和列,显示总计数据。margins_name可以自定义合计的名称。
示例 4:多层索引和复杂透视
可以使用多个列创建多层索引的透视表。
实例
import pandas as pd
# 1. 创建包含多个分类变量的数据
data = pd.DataFrame({
'year': [2022, 2022, 2022, 2023, 2023, 2023],
'quarter': ['Q1', 'Q2', 'Q3', 'Q1', 'Q2', 'Q3'],
'product': ['A', 'A', 'B', 'B', 'A', 'B'],
'sales': [100, 150, 200, 220, 180, 250]
})
print("=== 数据 ===")
print(data)
# 2. 使用多个列作为行索引
print("n=== 多年份多季度透视 ===")
pivot = pd.pivot_table(data, values='sales', index=['year', 'quarter'], columns='product', aggfunc='sum')
print(pivot)
# 3. 多个列作为列索引
print("n=== 复杂交叉透视 ===")
pivot_multi = pd.pivot_table(data, values='sales', index='year', columns=['product', 'quarter'], aggfunc='sum')
print(pivot_multi)
# 4. 使用 fill_value 处理缺失值
print("n=== 填充缺失值 ===")
pivot_fill = pd.pivot_table(data, values='sales', index=['year', 'quarter'], columns='product', aggfunc='sum', fill_value=0)
print(pivot_fill)
# 1. 创建包含多个分类变量的数据
data = pd.DataFrame({
'year': [2022, 2022, 2022, 2023, 2023, 2023],
'quarter': ['Q1', 'Q2', 'Q3', 'Q1', 'Q2', 'Q3'],
'product': ['A', 'A', 'B', 'B', 'A', 'B'],
'sales': [100, 150, 200, 220, 180, 250]
})
print("=== 数据 ===")
print(data)
# 2. 使用多个列作为行索引
print("n=== 多年份多季度透视 ===")
pivot = pd.pivot_table(data, values='sales', index=['year', 'quarter'], columns='product', aggfunc='sum')
print(pivot)
# 3. 多个列作为列索引
print("n=== 复杂交叉透视 ===")
pivot_multi = pd.pivot_table(data, values='sales', index='year', columns=['product', 'quarter'], aggfunc='sum')
print(pivot_multi)
# 4. 使用 fill_value 处理缺失值
print("n=== 填充缺失值 ===")
pivot_fill = pd.pivot_table(data, values='sales', index=['year', 'quarter'], columns='product', aggfunc='sum', fill_value=0)
print(pivot_fill)
运行结果预期:
=== 数据 === year quarter product sales 0 2022 Q1 A 100 1 2022 Q2 A 150 2 2022 Q3 B 200 3 2023 Q1 B 220 4 2023 Q2 A 180 5 2023 Q3 B 250 === 多年份多季度透视 === product A B year quarter 2022 Q1 100.0 NaN 2022 Q2 150.0 NaN 2022 Q3 NaN 200.0 2023 Q1 NaN 220.0 2023 Q2 180.0 NaN 2023 Q3 NaN 250.0 === 复杂交叉透视 === product A B quarter Q1 Q2 Q3 Q1 Q2 Q3 year 2022 100 150 200 NaN NaN NaN 2023 NaN 180 250 NaN NaN NaN === 填充缺失值 === product A B year quarter 2022 Q1 100 0 2022 Q2 150 0 2022 Q3 0 200 2023 Q1 0 220 2023 Q2 180 0 2023 Q3 0 250
代码解析:
- 多层索引通过列表形式指定
index=['year', 'quarter']实现。 fill_value=0将缺失数据统一填充为 0,便于后续计算。
提示:
pd.pivot_table()提供了强大的数据透视功能。如果只需要统计两个分类变量的频次,pd.crosstab()可能更简洁。pd.crosstab()返回频次数值,而pivot_table()能计算平均值、总和、标准差等多种统计量。pd.crosstab()可视为pivot_table()在aggfunc='count'时的特例。

Pandas 常用函数