PythonのPandasにおける MultiIndex(階層的インデックス) について、基礎から応用まで詳しく解説します。
長めに整理しますので、じっくり理解できると思います。
目次
MultiIndexとは?
Pandasの MultiIndex は、行や列に「階層構造を持つインデックス」を持たせる機能です。
通常のインデックスは1次元(例: 0, 1, 2… や “A”, “B”…)ですが、MultiIndexを使うとインデックスを複数のレベルに分けられます。
例
import pandas as pd
import numpy as np
arrays = [
["A", "A", "B", "B"],
[1, 2, 1, 2]
]
multi_index = pd.MultiIndex.from_arrays(arrays, names=("letter", "number"))
df = pd.DataFrame(np.random.randn(4, 2), index=multi_index, columns=["X", "Y"])
print(df)
ここで、行インデックスは letter
と number
の2階層になっています。
これが MultiIndexの基本形 です。
MultiIndexの作り方
from_arrays
リストや配列から作る
pd.MultiIndex.from_arrays([["A","A","B"], [1,2,1]])
from_tuples
タプルのリストから作る
pd.MultiIndex.from_tuples([("A",1),("A",2),("B",1)])
from_product
直積から作る
pd.MultiIndex.from_product([["A","B"], [1,2]])
groupbyで自動生成
df = pd.DataFrame({"category": ["A","A","B","B"], "value": [1,2,3,4]})
df.groupby(["category"]).sum()
このとき category
がMultiIndexの一部になる。
MultiIndexの操作
部分選択(.loc)
import pandas as pd
import numpy as np
# サンプルデータ作成
arrays = [
["A", "A", "B", "B"],
[1, 2, 1, 2]
]
multi_index = pd.MultiIndex.from_arrays(arrays, names=("letter", "number"))
df = pd.DataFrame(np.random.randn(4, 2), index=multi_index, columns=["X", "Y"])
# 部分選択
print(df.loc["A"]) # letter = "A" の行を取得
print(df.loc[("A", 1)]) # letter="A" & number=1 の行を取得
スライス
# A のすべての number
print(df.loc[("A", slice(None)), :])
xs(クロスセクション)
# letter = "A" のデータを抽出
print(df.xs("A", level="letter"))
# number = 1 のデータを抽出
print(df.xs(1, level="number"))
reset_index
# MultiIndexを通常の列に変換
df_reset = df.reset_index()
print(df_reset)
→ MultiIndexを通常の列に変換できる。
set_index
# 通常列から再びMultiIndexに戻す
df2 = df_reset.set_index(["letter", "number"])
print(df2)
→ 再度MultiIndexに戻せる。
MultiIndexのユースケース
- ピボットテーブル(クロス集計)
df = pd.DataFrame({
"city": ["Tokyo","Tokyo","Osaka","Osaka"],
"year": [2020, 2021, 2020, 2021],
"sales": [100, 120, 90, 110]
})
pivot = df.pivot_table(values="sales", index="city", columns="year")
print(pivot)
# → columns が MultiIndexになる
columns
が MultiIndex
になる。
- 階層的なグルーピング
grouped = df.groupby(["city","year"]).sum()
print(grouped)
# → 行インデックスがMultiIndexになる
行インデックスが階層化される。
- 時系列データ
dates = pd.date_range("2025-01-01", periods=4)
tickers = ["AAPL","GOOG"]
multi_index = pd.MultiIndex.from_product([tickers, dates], names=["ticker", "date"])
ts_df = pd.DataFrame(np.random.randn(len(multi_index), 2), index=multi_index, columns=["Open", "Close"])
print(ts_df.head())
# → "銘柄 × 日付" のMultiIndex
例えば「銘柄 × 日付」のような形で管理。
MultiIndexのメリットとデメリット
メリット
- データを 2次元以上の階層構造で直感的に表現できる
- 複数条件でのアクセスや集計が簡単
- Excelのピボットテーブル的な表現が可能
デメリット
- 初心者には直感的に扱いづらい
.loc
や.xs
の書き方が複雑になる- 集計後に「見やすさのために
reset_index()
が必要」な場面が多い
実践Tips
- 分析後に最終的な出力を見やすくするなら
reset_index()
- 部分抽出には
.xs()
が便利 - 階層が深すぎると混乱するので、2~3階層が限界
- 表示を整えるときは
swaplevel
やsort_index
を使う
まとめ
- MultiIndex = 行・列を多階層にできる仕組み
- 作り方は
from_arrays
,from_tuples
,groupby
,pivot_table
など - 抽出は
.loc
,.xs
,slice
を使い分ける - ユースケースは「クロス集計」「複合条件での集計・分析」「時系列管理」など
- ただし扱いづらいので、最終出力は
reset_index()
しておくと分かりやすい
以上、PythonのPandasのMultiindexについてでした。
最後までお読みいただき、ありがとうございました。