Python | データ処理:pivot

Python
スポンサーリンク

概要(pivotは「縦長データを横に広げて“見やすい表”に再配置する」)

pandasのpivotは、行ラベル・列ラベル・値列を指定して、縦に並んだレコードを「行×列」の表へ並べ替えるメソッドです。Excelのピボットテーブルに似ていますが、pivotは集計をしません。「同じ行×列の組み合わせが一意である」ことが前提です。重複があるなら、集計できるpivot_tableを使うのが安全です。


基本の使い方(index・columns・valuesの3点を押さえる)

もっとも基本的なピボット

import pandas as pd

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

out = df.pivot(index="store", columns="item", values="sales")
print(out)
# item   apple  banana
# store
# A         10      12
# B          7       9
Python

index(行ラベル)、columns(列ラベル)、values(セルに置く値)を指定します。指定した行×列の組み合わせが重複していないときに使えます。

重複があるときはpivot_tableを使う

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

# 同じ (store="A", item="apple") が2件 → pivotはエラー
# df_dup.pivot(index="store", columns="item", values="sales")

out = pd.pivot_table(df_dup, index="store", columns="item", values="sales", aggfunc="sum")
print(out)
# item   apple  banana
# store
# A         23      12
Python

pivotは重複でエラーになります。pivot_tableならaggfunc(sum, mean, countなど)で集計して安全に整形できます。


重要ポイントの深掘り(重複対策・欠損・複数値・MultiIndex)

重複対策(pivotでダメならpivot_table)

  • 判断基準: indexとcolumnsで定義される組み合わせが一意でない場合はpivotが失敗する。
  • 解決策: pivot_tableでaggfuncを指定して集計する(sum/mean/count/firstなど)。
pd.pivot_table(df, index="store", columns="item", values="sales", aggfunc="mean")
Python

欠損値の扱い(fill_valueで穴埋め)

  • 欠損が出る理由: 行×列の組み合わせが存在しないセルはNaNになる。
  • 解決策: pivot_tableならfill_valueで穴埋めできる。
out = pd.pivot_table(df, index="store", columns="item", values="sales", aggfunc="sum", fill_value=0)
Python

複数のvaluesを並べる(列が層構造になる)

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

out = df2.pivot(index="store", columns="item", values=["sales", "cost"])
print(out)
# valuesが複数だと列がMultiIndex(階層)になる
Python

valuesを複数渡すと、列が階層(MultiIndex)になります。後で列名をフラット化するなどの整形が有効です。

行・列を複数にする(MultiIndex)

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

out = df3.pivot(index=["year", "store"], columns="item", values="sales")
print(out)
# 年×店を行の階層にできる
Python

indexやcolumnsをリストで指定すると階層化できます。グループ集計や並べ替えの前準備として有用です。


実践例(売上整形・比率計算・集計付きピボット)

例1:縦長売上を「店×商品」へ整形

df = pd.DataFrame({
    "store": ["A", "A", "B", "B"],
    "item":  ["apple", "banana", "apple", "banana"],
    "sales": [10, 12, 7, 9]
})
wide = df.pivot(index="store", columns="item", values="sales")
wide = wide.reset_index()  # 行インデックスを列へ戻す(保存や出力用に便利)
print(wide)
Python

まずpivotで「見やすく」整形し、必要ならreset_indexでフラットな表に戻します。

例2:重複があるデータを合計で整える

df = pd.DataFrame({
    "month": ["2025-01", "2025-01", "2025-02", "2025-02"],
    "item":  ["apple", "apple", "apple", "banana"],
    "sales": [10, 5, 12, 7]
})
# 同じ (month, item) が重複 → 合計で整形
pt = pd.pivot_table(df, index="month", columns="item", values="sales", aggfunc="sum", fill_value=0)
print(pt)
Python

現実のデータは重複しやすいので、pivot_tableのaggfuncとfill_valueが定番です。

例3:比率列を追加する(後処理のコツ)

pt = pd.pivot_table(df, index="month", columns="item", values="sales", aggfunc="sum", fill_value=0)
pt["total"] = pt.sum(axis=1)
pt["apple_ratio"] = (pt.get("apple", 0) / pt["total"]).round(3)
print(pt)
Python

pivot後は「合計」「比率」を列演算で追加できます。getで列がない場合の安全な参照も覚えておくと便利です。


よくあるつまずきと回避(エラー・列名・整形の戻し方)

ValueError: Index contains duplicate entries

  • 原因: pivotで行×列の組み合わせが重複している。
  • 回避: pivot_table+aggfuncを使う。重複を事前に集計して一意にする。

列名が階層で扱いづらい

  • 対策: 列名をフラット化する。
pt.columns = ["_".join(map(str, c)).strip() if isinstance(c, tuple) else c for c in pt.columns]
Python

整形を元に戻したい(ワイド→ロング)

  • 手段: stackやmeltを使う。
# ワイド→ロング(列を縦へ)
long = pt.reset_index().melt(id_vars="month", var_name="item", value_name="sales")
# または、階層列なら stack() → reset_index() → rename()
Python

まとめ(pivotで“再配置”、重複はpivot_tableで“集計しながら再配置”)

pivotはindex・columns・valuesの3つを指定して、縦長データを「行×列」に再配置する道具です。重複があるならpivot_tableでaggfuncを使って集計し、fill_valueで欠損を埋める。valuesや行列に複数を指定すれば階層化も可能で、後処理ではreset_index・列演算・stack/meltで整形を仕上げる。最初に「重複の有無」を見極め、pivotとpivot_tableを使い分ければ、初心者でも迷わず美しいテーブルが作れます。

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