Pandas データ再形成(pivot / melt / stack / unstack)
データ再形成はデータ分析における一般的な操作で、データのレイアウト構造を変更するために使用されます。Pandas は pivot、melt、stack、unstack などの関数を提供し、ロング形式とワイド形式の間の変換を実現します。
pivot ピボットテーブル
pivotロング形式のデータをワイド形式に変換します。Excel のピボットテーブル機能に似ています。
基本的な使い方
例
import pandas as pd
# 创建长格式数据
df = pd.DataFrame({
"日期": ["2024-01-01", "2024-01-01", "2024-01-02", "2024-01-02"],
"产品": ["A", "B", "A", "B"],
"销量": [100, 150, 120, 90]
})
print("长格式数据:")
print(df)
print()
# ワイド形式に変換
pivot_df = df.pivot(index="日期", columns="产品", values="销量")
print("宽格式数据:")
print(pivot_df)
# 创建长格式数据
df = pd.DataFrame({
"日期": ["2024-01-01", "2024-01-01", "2024-01-02", "2024-01-02"],
"产品": ["A", "B", "A", "B"],
"销量": [100, 150, 120, 90]
})
print("长格式数据:")
print(df)
print()
# ワイド形式に変換
pivot_df = df.pivot(index="日期", columns="产品", values="销量")
print("宽格式数据:")
print(pivot_df)
多重インデックス
例
import pandas as pd
df = pd.DataFrame({
"年份": ["2024", "2024", "2024", "2024"],
"季度": ["Q1", "Q1", "Q2", "Q2"],
"产品": ["A", "B", "A", "B"],
"销量": [100, 150, 120, 90]
})
print("数据:")
print(df)
print()
# 多重索引透视
pivot_df = df.pivot(index=["年份", "季度"], columns="产品", values="销量")
print("多重索引透视:")
print(pivot_df)
df = pd.DataFrame({
"年份": ["2024", "2024", "2024", "2024"],
"季度": ["Q1", "Q1", "Q2", "Q2"],
"产品": ["A", "B", "A", "B"],
"销量": [100, 150, 120, 90]
})
print("数据:")
print(df)
print()
# 多重索引透视
pivot_df = df.pivot(index=["年份", "季度"], columns="产品", values="销量")
print("多重索引透视:")
print(pivot_df)
集計関数
例
import pandas as pd
# 値が重複する場合
df = pd.DataFrame({
"日期": ["2024-01-01", "2024-01-01", "2024-01-01", "2024-01-02"],
"产品": ["A", "A", "B", "B"],
"销量": [100, 110, 80, 90]
})
print(重複値のデータ:)
print(df)
print()
# pivot 默认不支持重复值,需要用 pivot_table 并指定聚合函数
pivot_df = df.pivot_table(index="日期", columns="产品", values="销量", aggfunc="sum")
print("使用 sum 聚合:")
print(pivot_df)
print()
# 使用 mean
print("使用 mean 聚合:")
print(df.pivot_table(index="日期", columns="产品", values="销量", aggfunc="mean"))
# 値が重複する場合
df = pd.DataFrame({
"日期": ["2024-01-01", "2024-01-01", "2024-01-01", "2024-01-02"],
"产品": ["A", "A", "B", "B"],
"销量": [100, 110, 80, 90]
})
print(重複値のデータ:)
print(df)
print()
# pivot 默认不支持重复值,需要用 pivot_table 并指定聚合函数
pivot_df = df.pivot_table(index="日期", columns="产品", values="销量", aggfunc="sum")
print("使用 sum 聚合:")
print(pivot_df)
print()
# 使用 mean
print("使用 mean 聚合:")
print(df.pivot_table(index="日期", columns="产品", values="销量", aggfunc="mean"))
pivot重複値は許可されません。重複値がある場合はpivot_table集計関数を指定してください。
melt 逆ピボット
meltワイド形式のデータをロング形式に変換します。pivot の逆操作です。
例
import pandas as pd
# 创建宽格式数据
df = pd.DataFrame({
"日期": ["2024-01-01", "2024-01-02"],
"A": [100, 120],
"B": [150, 90]
})
print("宽格式数据:")
print(df)
print()
# ロング形式に変換
melted = df.melt(id_vars="日期", var_name="产品", value_name="销量")
print("长格式数据:")
print(melted)
# 创建宽格式数据
df = pd.DataFrame({
"日期": ["2024-01-01", "2024-01-02"],
"A": [100, 120],
"B": [150, 90]
})
print("宽格式数据:")
print(df)
print()
# ロング形式に変換
melted = df.melt(id_vars="日期", var_name="产品", value_name="销量")
print("长格式数据:")
print(melted)
複数の列を保持
例
import pandas as pd
df = pd.DataFrame({
"城市": ["北京", "上海"],
"2023营收": [1000, 800],
"2023利润": [200, 150],
"2024营收": [1200, 950],
"2024利润": [250, 180]
})
print("宽格式:")
print(df)
print()
# 「城市」はそのままで、他の列を長形式に変換する
melted = df.melt(
id_vars="城市",
var_name="指标",
value_name="数值"
)
print("长格式:")
print(melted)
df = pd.DataFrame({
"城市": ["北京", "上海"],
"2023营收": [1000, 800],
"2023利润": [200, 150],
"2024营收": [1200, 950],
"2024利润": [250, 180]
})
print("宽格式:")
print(df)
print()
# 「城市」はそのままで、他の列を長形式に変換する
melted = df.melt(
id_vars="城市",
var_name="指标",
value_name="数值"
)
print("长格式:")
print(melted)
stack と unstack
stack と unstack は MultiIndex 専用の再形成関数です。
unstack
例
import pandas as pd
# 多層インデックスを持つデータを作成
df = pd.DataFrame({
"A": [1, 2, 3, 4],
"B": [5, 6, 7, 8]
}, index=pd.MultiIndex.from_tuples(
[("X", 1), ("X", 2), ("Y", 1), ("Y", 2)],
names=["类别", "编号"]
))
print("多层索引数据:")
print(df)
print()
# unstack は内側のインデックスを列に変換する
print("unstack 后:")
print(df.unstack())
# 多層インデックスを持つデータを作成
df = pd.DataFrame({
"A": [1, 2, 3, 4],
"B": [5, 6, 7, 8]
}, index=pd.MultiIndex.from_tuples(
[("X", 1), ("X", 2), ("Y", 1), ("Y", 2)],
names=["类别", "编号"]
))
print("多层索引数据:")
print(df)
print()
# unstack は内側のインデックスを列に変換する
print("unstack 后:")
print(df.unstack())
stack
例
import pandas as pd
# 创建宽格式(带列索引)
df = pd.DataFrame({
("A", "X"): [1, 2],
("A", "Y"): [3, 4],
("B", "X"): [5, 6],
("B", "Y"): [7, 8]
})
print("带多层列索引:")
print(df)
print()
# stack は列インデックスを内側のインデックスに変換する
print("stack 后:")
print(df.stack())
# 创建宽格式(带列索引)
df = pd.DataFrame({
("A", "X"): [1, 2],
("A", "Y"): [3, 4],
("B", "X"): [5, 6],
("B", "Y"): [7, 8]
})
print("带多层列索引:")
print(df)
print()
# stack は列インデックスを内側のインデックスに変換する
print("stack 后:")
print(df.stack())
実践:業務レポートの変換
例
import pandas as pd
# 模拟业务数据 - 销售记录
sales = pd.DataFrame({
"日期": ["2024-01"] * 4,
"产品": ["手机", "电脑", "平板", "耳机"],
"渠道": ["线上", "线上", "线下", "线上"],
"销售额": [10000, 20000, 8000, 5000]
})
print("原始销售数据:")
print(sales)
print()
# 使用 pivot 转换
pivot = sales.pivot_table(
index="产品",
columns="渠道",
values="销售额",
aggfunc="sum",
fill_value=0
)
print("渠道销售透视:")
print(pivot)
print()
# ロング形式に戻す
print("長形式に戻す:")
print(pivot.reset_index().melt(id_vars="产品", var_name="渠道", value_name="销售额"))
# 模拟业务数据 - 销售记录
sales = pd.DataFrame({
"日期": ["2024-01"] * 4,
"产品": ["手机", "电脑", "平板", "耳机"],
"渠道": ["线上", "线上", "线下", "线上"],
"销售额": [10000, 20000, 8000, 5000]
})
print("原始销售数据:")
print(sales)
print()
# 使用 pivot 转换
pivot = sales.pivot_table(
index="产品",
columns="渠道",
values="销售额",
aggfunc="sum",
fill_value=0
)
print("渠道销售透视:")
print(pivot)
print()
# ロング形式に戻す
print("長形式に戻す:")
print(pivot.reset_index().melt(id_vars="产品", var_name="渠道", value_name="销售额"))
再形成関数の選択
| 関数 | 用途 | 典型的なシナリオ |
|---|---|---|
pivot |
ロング→ワイド | 行と列の変換 |
pivot_table |
ロング→ワイド(集計付き) | 重複値がある場合 |
melt |
ワイド→ロング | データ整理 |
unstack |
インデックス→列 | 多重インデックス |
stack |
列→インデックス | 多重インデックス |
その他の拡張データ再形成の目的は、データを分析や表示に適した形にすることです。下流の要件に応じて適切な変換方法を選択してください。