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

Pandas pd.pivot_table() 函数

Pandas 常用函数 Pandas 常用函数


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)

运行结果预期:

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

运行结果预期:

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

运行结果预期:

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

运行结果预期:

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