现在位置: 首页 > Pandas 教程 > 正文

Pandas DataFrame.pivot_table() 函数

Pandas 常用函数 Pandas 常用函数


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)

运行结果预期:

=== 销售数据 ===
    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

代码解析:

  1. 原始数据是长格式,每行记录一个产品在某地区的销售额。
  2. pivot_table() 将 product 作为行索引,region 作为列索引,sales 作为值。
  3. 使用 aggfunc='sum' 对销售额进行求和汇总。
  4. 结果是一个清晰的二维表格,便于比较不同产品在不同地区的销售表现。

示例 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)

运行结果预期:

=== 销售数据 ===
   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)

运行结果预期:

=== 无合计 ===
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)

运行结果预期:

=== 原始数据 ===
  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 常用函数 Pandas 常用函数