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()pivot はエラーになります。 - A製品のNorth地域での総売上は310(100+120+90)で、これは自動集計の結果です。
注意事項
重要なヒント:
pivot_table()とpivot()の主な違いは重複値の処理にあります。pivot_table は自動的に集約しますが、pivot はエラーになります。- 当
valuesパラメータを指定しない場合、すべての数値列が集約されます。marginsパラメータで追加される合計行/列はデータの後続処理に影響するため、使用時には注意が必要です。- 大規模なデータを処理する場合、pivot_table は多くのメモリを消費する可能性があるため、データ量の管理に注意してください。
その他の拡張