Python | データ処理:pivot_table

Python
スポンサーリンク

概要(pivot_tableは「集計しながら縦長データを行×列へ再配置する」)

pandasのpivot_tableは、Excelのピボットテーブルと同じ発想で「行(index)」「列(columns)」「値(values)」を指定し、合計や平均などの集計をしながら表を作ります。pivotと違い、同じ行×列の組み合わせが重複していてもaggfunc(集計関数)で安全にまとめられるのが最大の強みです。


基本の書き方(index・columns・values・aggfuncを押さえる)

最小の例(店×商品で売上合計を作る)

import pandas as pd

df = pd.DataFrame({
    "store": ["A", "A", "B", "B", "A"],
    "item":  ["apple", "apple", "banana", "apple", "banana"],
    "sales": [10, 13, 9, 7, 12]
})

pt = pd.pivot_table(
    df,
    index="store",          # 行ラベル
    columns="item",         # 列ラベル
    values="sales",         # セルに置く値
    aggfunc="sum"           # 集計方法(合計)
)
print(pt)
# item   apple  banana
# store
# A         23      12
# B          7       9
Python

index・columns・valuesの3点セットと、aggfunc(sum/mean/count など)を指定します。重複行を自動で集計してくれるため、現実のデータで扱いやすいです。

よく使う集計関数(sum/mean/count/first)

# 平均
pd.pivot_table(df, index="store", columns="item", values="sales", aggfunc="mean")

# 件数(カウント)
pd.pivot_table(df, index="store", columns="item", values="sales", aggfunc="count")

# 最初の値(重複があっても先頭だけ拾う)
pd.pivot_table(df, index="store", columns="item", values="sales", aggfunc="first")
Python

重要ポイントの深掘り(欠損の穴埋め・総計・複数値・階層化)

欠損を埋める(fill_value)

pt = pd.pivot_table(
    df,
    index="store", columns="item", values="sales",
    aggfunc="sum", fill_value=0
)
print(pt)  # 組み合わせがないセルは0で埋まる
Python

行×列に存在しない組み合わせはNaNになります。fill_valueを指定すると穴埋めできます。

総計(margins=True と margins_name)

pt = pd.pivot_table(
    df, index="store", columns="item", values="sales",
    aggfunc="sum", fill_value=0, margins=True, margins_name="Total"
)
print(pt)
# 行・列に総計が追加され、俯瞰しやすくなる
Python

margins=Trueで行と列の総計(小計・総計)を自動追加できます。

valuesを複数指定(列が階層化)

df2 = pd.DataFrame({
    "store": ["A","A","B","B","A"],
    "item":  ["apple","banana","apple","banana","banana"],
    "sales": [10,12,7,9,12],
    "cost":  [6,7,5,6,7]
})

pt = pd.pivot_table(
    df2, index="store", columns="item", values=["sales", "cost"], aggfunc="sum", fill_value=0
)
print(pt)  # 列がMultiIndex(階層)になる
Python

valuesを複数渡すと列が階層化されます。出力後に列名をフラット化すると扱いやすくなります。

行・列を複数指定(MultiIndex)

df3 = pd.DataFrame({
    "year":  [2024, 2024, 2025, 2025, 2025],
    "store": ["A", "B", "A", "B", "A"],
    "item":  ["apple", "apple", "apple", "banana", "banana"],
    "sales": [10, 7, 12, 9, 11]
})

pt = pd.pivot_table(
    df3, index=["year", "store"], columns="item", values="sales", aggfunc="sum", fill_value=0
)
print(pt)  # 年×店の階層行インデックス
Python

indexやcolumnsにリストを渡すと階層化でき、分析の切り口を増やせます。


実践例(重複データの整形・比率作成・列名フラット化)

月×商品で合計と欠損埋め(基本整形の型)

df = pd.DataFrame({
    "month": ["2025-01","2025-01","2025-02","2025-02","2025-02"],
    "item":  ["apple","banana","apple","banana","banana"],
    "sales": [10,7,12,9,6]
})

pt = pd.pivot_table(
    df, index="month", columns="item", values="sales",
    aggfunc="sum", fill_value=0
)
print(pt)
Python

重複をまとめ、抜けている商品は0で埋める定番パターンです。

合計・比率列を後から追加(派生指標の作り方)

pt["total"] = pt.sum(axis=1)
pt["apple_ratio"] = (pt.get("apple", 0) / pt["total"]).replace([float("inf")], 0).round(3)
print(pt)
Python

合計と比率は列演算で簡単に追加できます。getで安全に列参照し、ゼロ割の特例も吸収します。

複数valuesの列名をフラット化(扱いやすくする整形)

# 先ほどの df2 → pt(MultiIndex列)をフラット化
pt.columns = [
    "_".join(map(str, c)).strip() if isinstance(c, tuple) else c
    for c in pt.columns
]
print(pt)  # 例: sales_apple, cost_banana のように平坦な列名へ
Python

階層列はそのままでも扱えますが、列選択や保存を楽にするならフラット化が有効です。


つまずき対策(pivotとの違い・重複エラー・カテゴリ・並び)

pivotとの違いを理解する(エラーになるならpivot_tableへ)

# pivotは「同じ行×列の組み合わせ」が重複すると ValueError
# pivot_tableはaggfuncでまとめるため安全に整形できる
Python

重複があるのが普通のデータなので、最初からpivot_tableを使う方が失敗が少ないです。

並び順を整える(並べ替えやカテゴリで順序固定)

pt = pt.sort_index()              # 行の並び替え
pt = pt.reindex(sorted(pt.columns), axis=1)  # 列の並び替え

# カテゴリ型で並び順を固定(列側に適用する例)
order = pd.CategoricalDtype(categories=["apple", "banana", "cherry"], ordered=True)
df["item"] = df["item"].astype(order)
pt = pd.pivot_table(df, index="month", columns="item", values="sales", aggfunc="sum")
Python

並びを安定させると、グラフ化やレポート出力が整います。

欠損の扱い方を先に決める(fill_value/あと処理)

pt = pd.pivot_table(df, index="month", columns="item", values="sales", aggfunc="sum", fill_value=0)
# もしくは後でまとめて処理
# pt = pt.fillna(0).astype(int)
Python

最初に「欠損は0にするか、NaNのままか」を決めておくと、その後の計算が安定します。


まとめ(pivot_tableは“重複OKの再配置+集計”。fill・総計・階層化で仕上げる)

pivot_tableは、index・columns・valuesを指定して「集計しながら行×列へ再配置」できる道具です。重複はaggfuncで安全にまとめ、fill_valueで欠損を埋め、marginsで総計を付ければ俯瞰が容易になります。valuesや行列を複数にすると階層化も可能で、必要なら列名のフラット化・合計や比率の派生列を加えて仕上げます。まずは「pivotよりpivot_table」「aggfuncとfill_value」を基本形にする—これが初心者に最も効く実践的な使い方です。

タイトルとURLをコピーしました