Pandas Pivot vs Melt:データを正しく整形する
Updated on
整形ステップが遅いと分析や可視化も止まります。間違った方法を選ぶと行が重複したり、値が落ちたり、幅広テーブルが扱いづらくなります。
PASの流れ:
- 問題: 乱れた wide/long データは集計やグラフを遅らせる。
- あおり: 重複があるのに
pivotを使うとエラー、meltを誤用すると行が増えすぎたり ID を失う。 - 解決: Tidy フローを徹底—重複があるなら
pivot_table、一意キーならpivot、long へはmelt、MultiIndex はstack/unstackで微調整。
クイックガイド
| メソッド | 方向 | 使う場面 | 重複を処理? |
|---|---|---|---|
pivot | long → wide | キーが一意 | 🚫 (重複でエラー) |
pivot_table | long → wide | 重複や集計が必要 | ✅ aggfunc で処理 |
melt | wide → long | 列を行に正規化 | N/A |
stack / unstack | wide ↔ long(インデックス階層) | MultiIndex 用 | N/A |
サンプルデータ
import pandas as pd
sales = pd.DataFrame({
"region": ["NA", "NA", "EU", "EU"],
"quarter": ["Q1", "Q2", "Q1", "Q2"],
"product": ["A", "A", "A", "A"],
"revenue": [120, 140, 110, 150],
"units": [10, 11, 9, 12],
})pivot でワイド化
wide = sales.pivot(index="region", columns="quarter", values="revenue")region+quarterの組み合わせが一意であることが必要。- 必要なら
.reset_index()でフラット化。
集計付きワイド化 (pivot_table)
table = sales.pivot_table(
index="region",
columns="quarter",
values="revenue",
aggfunc="sum",
margins=True,
margins_name="Total"
)- 重複を集計で処理。
fill_value=0で欠損を埋めてエクスポートをきれいに。
複数値・複数集計
multi = sales.pivot_table(
index="region",
columns="quarter",
values=["revenue", "units"],
aggfunc={"revenue": "sum", "units": "mean"},
)カラムを平坦化:
multi.columns = [f"{metric}_{col}" for metric, col in multi.columns]
multi = multi.reset_index()melt でロング化
long = sales.melt(
id_vars=["region", "quarter"],
value_vars=["revenue", "units"],
var_name="metric",
value_name="value",
)- tidy データを期待する可視化ライブラリに最適。
value_varsで展開する列を指定。
MultiIndex 用の stack / unstack
stacked = table.stack()
unstacked = stacked.unstack()- キーを再定義せずにレベル順を入れ替えられる。
stack(level="quarter")やunstack(level=-1)でレベル指定。
よくあるエラー
| 問題 | 解決 |
|---|---|
pivot で Index contains duplicate entries | 集計付きの pivot_table を使う。 |
| 列の順番が想定外 | 列を並び替え: table = table.reindex(sorted(table.columns), axis=1)。 |
| MultiIndex が読みにくい | pivot_table 後にカラムを平坦化。 |
| 変換後に欠損が増える | fill_value を使うか、stack(dropna=False) で空欄を保持。 |
ワークフローのコツ
- まず正規化:
melt→groupby/agg→pivot_tableで最終形を作る。 - グラフ用途では long のままが扱いやすい。wide はレポート/エクスポート向き。
pivot_table後にtable.to_excel("report.xlsx")で即出力。
関連ガイド
まとめ
- キーが一意なら
pivot、重複・集計が必要ならpivot_table、long 化はmelt。 - 複雑なピボット後は MultiIndex を平坦化すると出力が楽。
- Reshape と
groupbyを組み合わせ、分析しやすいデータを素早く作る。