Pandas DataFrame.pivot_table() 関数

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()pivot はエラーになります。
  • A製品のNorth地域での総売上は310(100+120+90)で、これは自動集計の結果です。

注意事項

重要なヒント:

  • pivot_table()とpivot()の主な違いは重複値の処理にあります。pivot_table は自動的に集約しますが、pivot はエラーになります。
  • 当 valuesパラメータを指定しない場合、すべての数値列が集約されます。
  • marginsパラメータで追加される合計行/列はデータの後続処理に影響するため、使用時には注意が必要です。
  • 大規模なデータを処理する場合、pivot_table は多くのメモリを消費する可能性があるため、データ量の管理に注意してください。

Pandas よく使う関数

その他の拡張