概要(meltは「横持ちの列を縦に溶かして整然データへ変換する」)
pandasのmeltは、ワイド形式(横持ち)をロング形式(縦持ち)へ変換するためのメソッドです。列として並んだ複数の計測値(例: Math, English, Science)を「変数名(var_name)」「値(value_name)」の2列にまとめ、分析や可視化に使いやすい“整然データ”へ変えます。Excelの「ピボットの逆」をイメージすると掴みやすく、Seabornや集計処理との相性が抜群です。
基本の使い方(id_vars・value_vars・var_name・value_name)
最小例(教科ごとのスコア列を縦へ)
import pandas as pd
df = pd.DataFrame({
"ID": [1, 2, 3],
"Name": ["Alice", "Bob", "Charlie"],
"Math": [90, 80, 85],
"English": [85, 95, 90],
})
melted = df.melt(
id_vars=["ID", "Name"], # そのまま残す識別列
value_vars=["Math", "English"], # 縦へ溶かす対象列
var_name="Subject", # 列名を格納する列名
value_name="Score" # 値を格納する列名
)
print(melted)
# ID Name Subject Score
# 0 1 Alice Math 90
# 1 2 Bob Math 80
# 2 3 Charlie Math 85
# 3 1 Alice English 85
# 4 2 Bob English 95
# 5 3 Charlie English 90
Pythonid_varsに主キーや識別情報を指定し、value_varsに“縦にしたい列”を指定します。var_nameとvalue_nameを付けると後工程で扱いやすくなります。
value_varsを省略して「id以外をすべて溶かす」
melted_all = df.melt(id_vars=["ID", "Name"], var_name="Subject", value_name="Score")
Python対象列が多いときに便利です。id_varsで“残したい列”だけ指定し、他は全部縦持ちへ。
重要ポイントの深掘り(ignore_index・カテゴリ順・MultiIndex列)
ignore_indexで新しい連番インデックスへ
meltは元の行を複製して縦に増やすため、インデックスが重複しがちです。整形後の扱いやすさを優先するなら、reset_index(またはmelt後にreset_index)で連番へ振り直します。
melted = df.melt(id_vars=["ID", "Name"], var_name="Subject", value_name="Score").reset_index(drop=True)
Pythonカテゴリ順の固定(並べ替えの安定化)
Subjectの表示順(例: Math→English→Science)を固定したいときは、カテゴリ型を使うとグラフや表の並びを安定させられます。
melted["Subject"] = pd.Categorical(melted["Subject"], categories=["Math", "English"], ordered=True)
PythonMultiIndex列を持つ場合のmelt(col_levelと階層の扱い)
列が階層(MultiIndex)になっている場合は、必要な階層だけを溶かす指定ができます。まずは列をフラット化してからmeltするのがわかりやすい定石です。
# 例:MultiIndex列をフラット化して扱いやすく
df.columns = ["_".join(map(str, c)).strip() if isinstance(c, tuple) else c for c in df.columns]
melted = df.melt(id_vars=["ID", "Name"], var_name="Variable", value_name="Value")
Pythoncol_levelを使う方法もありますが、初心者は「一度フラット化→通常のmelt」が確実です。
実践例(前処理・可視化・ピボットとの往復)
可視化へ直行できる形へ(Seabornのbarplotやlineplotにそのまま渡す)
import pandas as pd
df = pd.DataFrame({
"Month": ["Jan", "Feb", "Mar"],
"ProductA": [150, 160, 175],
"ProductB": [90, 95, 110],
})
melted = df.melt(id_vars=["Month"], var_name="Product", value_name="Sales")
print(melted)
# Month Product Sales
# 0 Jan ProductA 150
# 1 Feb ProductA 160
# 2 Mar ProductA 175
# 3 Jan ProductB 90
# 4 Feb ProductB 95
# 5 Mar ProductB 110
# 可視化例(コメント):sns.lineplot(data=melted, x="Month", y="Sales", hue="Product")
Python「月×商品×売上」をロング形式にすると、色分けや凡例の制御が容易になります。
melt後に集計(groupby)で指標を作る
melted = df.melt(id_vars=["Month"], var_name="Product", value_name="Sales")
summary = (
melted
.groupby("Product", as_index=False)
.agg(mean_sales=("Sales", "mean"), max_sales=("Sales", "max"))
)
print(summary)
Pythonロング形式はgroupbyと相性が良く、平均や最大などの集計が直感的に書けます。
pivot_table(またはpivot)で“元の形へ戻す”往復の流れ
# ロング→ワイド(合計例)
wide = pd.pivot_table(
melted, index="Month", columns="Product", values="Sales", aggfunc="sum", fill_value=0
).reset_index()
print(wide)
Pythonmeltで縦へ、pivot_tableで横へ—この往復で、分析→出力(CSVや報告用の表)の両方に対応できます。重複がある現実データではpivotよりpivot_tableが安全です。
つまずき対策(識別列の消失・型の不一致・大規模データ)
識別列(id_vars)を忘れると紐付けが切れる
「誰のどの値か」を示す列(ID、日付、カテゴリなど)は必ずid_varsへ。これを忘れると、後工程でグループ化やフィルタができなくなります。
型の不一致を先に正規化(文字列・数値・日時)
溶かす対象列が文字列と数値で混在していると、value列のdtypeがobjectになりがちです。分析前にastypeで揃える、日時はto_datetimeで変換しておくと、後工程が安定します。
大規模データは段階処理で安全に
列数・行数が多い場合、いきなり全列をmeltせず、対象列を絞る→中間確認→追加、の段階処理が安全です。出力直前にはreset_indexで連番化、不要列のdropで軽量化しましょう。
例題(稼働指標のロング変換→比率計算→報告用に整形)
ワイドからロングへ溶かす
import pandas as pd
df = pd.DataFrame({
"date": ["2025-01-01", "2025-01-02", "2025-01-03"],
"active_users": [100, 120, 110],
"new_users": [30, 40, 35],
"churn_users": [5, 8, 6],
})
melted = df.melt(
id_vars=["date"],
value_vars=["active_users", "new_users", "churn_users"],
var_name="metric",
value_name="value"
)
print(melted.head())
Python比率や派生指標を追加(後処理のコツ)
# 例:日ごとの「新規率」= new / active
pivoted = pd.pivot_table(melted, index="date", columns="metric", values="value", aggfunc="sum", fill_value=0)
pivoted["new_rate"] = (pivoted["new_users"] / pivoted["active_users"]).replace([float("inf")], 0).round(3)
print(pivoted.reset_index())
Pythonmeltで整然化→pivot_tableで集計・派生列追加の流れは、レポート作成の定番です。
まとめ(meltは“列を溶かして縦へ”。id_varsで紐付け、var/value名でわかりやすく)
meltは、横持ちの複数列を「変数名」と「値」にまとめ、整然データへ変換するための最短ルートです。id_varsで識別列を残し、value_varsで対象列を選び、var_name・value_nameで意味を明確化する。必要に応じてreset_indexで連番化し、カテゴリ順やdtypeを整える。整然化したロング形式は、groupby・可視化・pivot_tableとの往復で圧倒的に扱いやすくなります。これを型として身につければ、初心者でも“迷わず、速く、正確に”データ整形ができるようになります。
