Pandas DataFrame.pivot_table() 函数
df.pivot_table() 是 DataFrame 的成员方法,用于创建数据透视表。它是 pivot() 的增强版,支持聚合操作,可以处理重复的行索引和列索引组合。
数据透视表是数据分析中最常用的工具之一,可以从不同角度对数据进行分组、汇总和重塑,便于发现数据中的规律和趋势。
单词释义: pivot_table 意为"透视表",是一种可以动态改变数据布局的表格,支持自动聚合重复数据。
基本语法与参数
df.pivot_table() 是 DataFrame 的实例方法,通过点运算符调用。
语法格式
DataFrame.pivot_table(values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')
参数说明
- 参数:
index- 类型: 列名、标签、标签列表或 None。
- 描述: 用作行索引的列。可以是单个列或多个列(列表),多个列会创建层次化索引。
- 参数:
columns- 类型: 列名或标签。
- 描述: 用作列索引的列,用于将唯一值展开为列名。
- 参数:
values- 类型: 列名、标签、标签列表或 None。
- 描述: 要聚合的数值列。如果不指定,会对所有数值列进行聚合。
- 参数:
aggfunc- 类型: 函数、字符串或函数列表。
- 描述: 聚合函数。常用值包括
'sum'(求和)、'mean'(平均值,默认)、'count'(计数)、'min'(最小值)、'max'(最大值)、'median'(中位数)、'std'(标准差)等。
- 参数:
fill_value- 类型: 标量或 None。
- 描述: 用于填充缺失值的数值。默认为 None,保留 NaN。
- 参数:
margins- 类型: 布尔值。
- 描述: 是否添加行列合计。默认为 False。设为 True 时会在行和列末尾添加汇总数据。
- 参数:
margins_name- 类型: 字符串。
- 描述: 合计行/列的名称,默认为 'All'。只有当 margins=True 时才有效。
函数说明
- 返回值: 返回一个 DataFrame,即数据透视表。
- 特点: 与
pivot()不同,pivot_table()不会因为重复的 index+columns 组合而报错,会自动使用aggfunc进行聚合。
实例
让我们通过一系列从简单到复杂的例子,彻底掌握 df.pivot_table() 的用法。
示例 1:基础用法 - 创建简单透视表
实例
import pandas as pd
# 1. 创建销售数据
sales = pd.DataFrame({
'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. 创建透视表 - 按产品和地区汇总销售额(默认聚合函数是mean)
pivot = sales.pivot_table(values='sales', index='product', columns='region', aggfunc='sum')
print("n=== df.pivot_table() 销售透视表(求和)===")
print(pivot)
# 1. 创建销售数据
sales = pd.DataFrame({
'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. 创建透视表 - 按产品和地区汇总销售额(默认聚合函数是mean)
pivot = sales.pivot_table(values='sales', index='product', columns='region', aggfunc='sum')
print("n=== df.pivot_table() 销售透视表(求和)===")
print(pivot)
运行结果预期:
=== 销售数据 ===
product region sales
0 A North 100
1 B North 150
2 C North 200
3 A South 180
4 B South 170
5 C South 160
6 A East 190
7 B East 200
8 C East 210
9 A West 220
10 B West 230
11 C West 240
=== df.pivot_table() 销售透视表(求和)===
region East North South West
product
A 190 100 180 220
B 200 150 170 230
C 210 200 160 240
代码解析:
- 原始数据是长格式,每行记录一个产品在某地区的销售额。
pivot_table()将 product 作为行索引,region 作为列索引,sales 作为值。- 使用
aggfunc='sum'对销售额进行求和汇总。 - 结果是一个清晰的二维表格,便于比较不同产品在不同地区的销售表现。
示例 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=== 销售额平均值 ===")
mean_result = sales.pivot_table(values='sales', index='product', columns='region', aggfunc='mean')
print(mean_result.round(1))
# 3. 同时使用多种聚合函数(传递字典)
print("n=== 多聚合函数 ===")
multi_agg = sales.pivot_table(
values='sales',
index='product',
columns='region',
aggfunc={'sales': ['sum', 'mean', 'max']}
)
print(multi_agg)
# 4. 不同列使用不同聚合函数
print("n=== 不同列不同聚合 ===")
diff_agg = sales.pivot_table(
values=['sales', 'quantity'],
index='product',
columns='region',
aggfunc={'sales': 'sum', 'quantity': 'mean'}
)
print(diff_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=== 销售额平均值 ===")
mean_result = sales.pivot_table(values='sales', index='product', columns='region', aggfunc='mean')
print(mean_result.round(1))
# 3. 同时使用多种聚合函数(传递字典)
print("n=== 多聚合函数 ===")
multi_agg = sales.pivot_table(
values='sales',
index='product',
columns='region',
aggfunc={'sales': ['sum', 'mean', 'max']}
)
print(multi_agg)
# 4. 不同列使用不同聚合函数
print("n=== 不同列不同聚合 ===")
diff_agg = sales.pivot_table(
values=['sales', 'quantity'],
index='product',
columns='region',
aggfunc={'sales': 'sum', 'quantity': 'mean'}
)
print(diff_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.0 105.0 200.0 220.0
B 200.0 150.0 185.0 230.0
=== 多聚合函数 ===
sales
sum mean max
region East North South West East North South West East North South West
product
A 190 210 200 220 190 105 200 220 190 110 200 220
B 200 150 370 230 200 150 185 230 200 150 190 230
=== 不同列不同聚合 ===
sales quantity
region East North South West East North South West
product
A 190 210 200 220 19.0 10.5 20.0 22.0
B 200 150 370 230 20.0 15.0 18.5 23.0
代码解析:
aggfunc可以是单个字符串(如 'sum', 'mean'),也可以是列表或字典。- 当传递字典时,可以为不同列指定不同的聚合函数。
- A产品在北区的销售额平均值为105((100+110)/2),这展示了 pivot_table() 自动处理重复值的能力。
示例 3:使用 margins 添加合计
使用 margins 参数可以添加行列合计,便于查看汇总数据。
实例
import pandas as pd
# 1. 创建销售数据
sales = pd.DataFrame({
'product': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'],
'region': ['North', 'North', 'South', 'South', 'East', 'East', 'West', 'West'],
'sales': [100, 150, 200, 180, 190, 200, 220, 230]
})
# 2. 无合计的透视表
print("=== 无合计 ===")
no_margins = sales.pivot_table(values='sales', index='product', columns='region', aggfunc='sum')
print(no_margins)
# 3. 添加行列合计
print("n=== 添加合计 (margins=True) ===")
with_margins = sales.pivot_table(
values='sales',
index='product',
columns='region',
aggfunc='sum',
margins=True
)
print(with_margins)
# 4. 自定义合计名称
print("n=== 自定义合计名称 ===")
custom_name = sales.pivot_table(
values='sales',
index='product',
columns='region',
aggfunc='sum',
margins=True,
margins_name='总计'
)
print(custom_name)
# 5. 多层行索引的透视表
print("n=== 多层行索引 ===")
multi_index = sales.pivot_table(
values='sales',
index=['product', 'region'],
aggfunc='sum'
)
print(multi_index)
# 1. 创建销售数据
sales = pd.DataFrame({
'product': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'],
'region': ['North', 'North', 'South', 'South', 'East', 'East', 'West', 'West'],
'sales': [100, 150, 200, 180, 190, 200, 220, 230]
})
# 2. 无合计的透视表
print("=== 无合计 ===")
no_margins = sales.pivot_table(values='sales', index='product', columns='region', aggfunc='sum')
print(no_margins)
# 3. 添加行列合计
print("n=== 添加合计 (margins=True) ===")
with_margins = sales.pivot_table(
values='sales',
index='product',
columns='region',
aggfunc='sum',
margins=True
)
print(with_margins)
# 4. 自定义合计名称
print("n=== 自定义合计名称 ===")
custom_name = sales.pivot_table(
values='sales',
index='product',
columns='region',
aggfunc='sum',
margins=True,
margins_name='总计'
)
print(custom_name)
# 5. 多层行索引的透视表
print("n=== 多层行索引 ===")
multi_index = sales.pivot_table(
values='sales',
index=['product', 'region'],
aggfunc='sum'
)
print(multi_index)
运行结果预期:
=== 无合计 === region East North South West product A 190 100 200 220 B 200 150 180 230 === 添加合计 (margins=True) === region East North South West All product A 190 100 200 220 710 B 200 150 180 230 760 All 390 250 380 450 1470 === 自定义合计名称 === region East North South West 总计 product A 190 100 200 220 710 B 200 150 180 230 760 总计 390 250 380 450 1470
代码解析:
margins=True会在透视表底部添加 "All" 行(合计)和右侧添加 "All" 列(合计)。- 可以使用
margins_name参数自定义合计的名称,如 '总计'。 - All 列显示的是各产品在不同地区的销售总和,All 行显示的是各地区所有产品的销售总和,右下角是全部数据的总和。
示例 4:使用 fill_value 处理缺失值
使用 fill_value 参数可以填充透视后产生的缺失值。
实例
import pandas as pd
import numpy as np
# 1. 创建数据(某些产品-地区组合不存在)
sales = pd.DataFrame({
'product': ['A', 'B', 'A', 'B'],
'region': ['North', 'North', 'South', 'South'],
'sales': [100, 150, 200, 180]
})
print("=== 原始数据 ===")
print(sales)
# 2. 不填充缺失值(默认)
print("n=== 不填充缺失值 ===")
no_fill = sales.pivot_table(values='sales', index='product', columns='region')
print(no_fill)
# 3. 填充缺失值为0
print("n=== 填充缺失值为0 ===")
fill_zero = sales.pivot_table(
values='sales',
index='product',
columns='region',
fill_value=0
)
print(fill_zero)
# 4. 演示重复值的自动聚合
data_with_duplicates = pd.DataFrame({
'product': ['A', 'A', 'B', 'B', 'A'],
'region': ['North', 'North', 'South', 'South', 'North'],
'sales': [100, 120, 200, 180, 90]
})
print("n=== 重复值数据 ===")
print(data_with_duplicates)
print("n=== 自动聚合(pivot会报错,pivot_table自动求和)===")
auto_agg = data_with_duplicates.pivot_table(
values='sales',
index='product',
columns='region',
aggfunc='sum'
)
print(auto_agg)
import numpy as np
# 1. 创建数据(某些产品-地区组合不存在)
sales = pd.DataFrame({
'product': ['A', 'B', 'A', 'B'],
'region': ['North', 'North', 'South', 'South'],
'sales': [100, 150, 200, 180]
})
print("=== 原始数据 ===")
print(sales)
# 2. 不填充缺失值(默认)
print("n=== 不填充缺失值 ===")
no_fill = sales.pivot_table(values='sales', index='product', columns='region')
print(no_fill)
# 3. 填充缺失值为0
print("n=== 填充缺失值为0 ===")
fill_zero = sales.pivot_table(
values='sales',
index='product',
columns='region',
fill_value=0
)
print(fill_zero)
# 4. 演示重复值的自动聚合
data_with_duplicates = pd.DataFrame({
'product': ['A', 'A', 'B', 'B', 'A'],
'region': ['North', 'North', 'South', 'South', 'North'],
'sales': [100, 120, 200, 180, 90]
})
print("n=== 重复值数据 ===")
print(data_with_duplicates)
print("n=== 自动聚合(pivot会报错,pivot_table自动求和)===")
auto_agg = data_with_duplicates.pivot_table(
values='sales',
index='product',
columns='region',
aggfunc='sum'
)
print(auto_agg)
运行结果预期:
=== 原始数据 === product region sales 0 A North 100 1 B North 150 2 A South 200 3 B South 180 === 不填充缺失值 === region North South product A 100.0 200.0 B 150.0 180.0 === 填充缺失值为0 === region North South product A 100 200 B 150 180 === 重复值数据 === product region sales 0 A North 100 1 A North 120 2 B South 200 3 B South 180 4 A North 90 === 自动聚合(pivot会报错,pivot_table自动求和)=== region North South product A 310 NaN B NaN 380
代码解析:
fill_value=0可以将缺失值填充为 0,便于后续计算。- 当有重复的 product-region 组合时,
pivot_table()会自动使用aggfunc进行聚合,而pivot()会报错。 - A 产品在 North 地区的总销售额是 310(100+120+90),这是自动求和的结果。
注意事项
重要提示:
pivot_table()与pivot()的主要区别在于对重复值的处理:pivot_table 会自动聚合,而 pivot 会报错。- 当
values参数不指定时,会对所有数值列进行聚合。margins参数添加的合计行/列会影响数据的后续处理,使用时需要注意。- 处理大规模数据时,pivot_table 可能会消耗较多内存,注意数据量控制。

Pandas 常用函数