MultiIndexの作成
pd.MultiIndex.from_tuplesまたは複数列へのset_indexで階層型の行インデックスを作成し、そのレベルを確認します。
「MultiIndexの作成」はCoddyKit上の無料Pandas & NumPy Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPandas & NumPy Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Pandas & NumPy Academyコースには全4レッスンが含まれています。
MultiIndexとは
MultiIndex(階層型インデックスとも呼ばれます)を使うと、PandasのDataFrameやSeriesで複数レベルの行ラベルを持てるようになります。データベースの複合キーのようなものだと考えてください。1つのラベルで行を識別する代わりに、(country, city)や(year, quarter)のようなタプルで識別します。MultiIndexは、パネルデータ、クロスセクション時系列データ、自然な2レベルのグループ構造を持つデータセットを表現するうえで不可欠です。
import pandas as pd
# A simple example: sales by country and city
data = {
'sales': [100, 200, 150, 300, 80, 120]
}
index = pd.MultiIndex.from_tuples(
[('USA', 'New York'), ('USA', 'Chicago'),
('UK', 'London'), ('UK', 'Manchester'),
('DE', 'Berlin'), ('DE', 'Munich')],
names=['country', 'city']
)
df = pd.DataFrame(data, index=index)
print(df)from_tuplesでMultiIndexを作成する
pd.MultiIndex.from_tuples(list_of_tuples, names=)は、MultiIndexを作成する最も明示的な方法です。各タプルが1つの行ラベルになり、その要素が各レベルになります。namesパラメータでは各レベルにラベルを割り当てます(例:['year', 'quarter'])。この方法は、行インデックスとして使用したい複合キーのリストがあらかじめ作成されている場合に便利です。
import pandas as pd
# Multi-level time index: year x quarter
tuples = [
(2022, 'Q1'), (2022, 'Q2'), (2022, 'Q3'), (2022, 'Q4'),
(2023, 'Q1'), (2023, 'Q2'), (2023, 'Q3'), (2023, 'Q4')
]
mi = pd.MultiIndex.from_tuples(tuples, names=['year', 'quarter'])
revenue = [120, 135, 145, 160, 130, 148, 162, 175]
df = pd.Series(revenue, index=mi, name='revenue_M')
print(df)from_productでMultiIndexを作成する
pd.MultiIndex.from_product(iterables, names=)は、複数のリストの直積(入力リストの要素から作られるすべての組み合わせ)からMultiIndexを作成します。すべてのレベルの組み合わせがデータに存在するべき場合に、最も便利な方法です。たとえば、3年 × 4四半期 × 5地域のすべての組み合わせから、60行の均衡パネルを自動的に作成できます。
import pandas as pd
import numpy as np
years = [2021, 2022, 2023]
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
# Cartesian product: 3 years x 4 quarters = 12 combinations
mi = pd.MultiIndex.from_product([years, quarters], names=['year', 'quarter'])
print('Number of index entries:', len(mi))
print('First 6 entries:', mi[:6].tolist())
# Create a DataFrame with this index
df = pd.DataFrame({'revenue': np.random.randint(100, 200, 12)}, index=mi)
print('\n', df.head())set_indexでMultiIndexを作成する
実務でMultiIndexを作成する最も一般的な方法は、グループ化に使う列を持つ通常のDataFrameから始め、df.set_index([col1, col2])を呼び出すことです。これにより、それらの列がデータ列からインデックスのレベルに移されます。結果はfrom_tuplesでインデックスを最初から作成した場合と同じですが、表形式のデータから1行で作成できます。
import pandas as pd
# Start with a flat DataFrame
df_flat = pd.DataFrame({
'country': ['USA', 'USA', 'UK', 'UK', 'DE', 'DE'],
'year': [2022, 2023, 2022, 2023, 2022, 2023],
'gdp_bn': [25000, 26000, 3100, 3200, 4200, 4350]
})
# Promote two columns to a MultiIndex
df = df_flat.set_index(['country', 'year'])
print(df)
print('\nIndex type:', type(df.index).__name__)
print('Index names:', df.index.names)MultiIndexのレベルを確認する
MultiIndexのデータは、levels(各レベルの一意な値)とcodes(レベル配列を参照する整数ポインタ)として保持されます。df.index.levelsまたはdf.index.get_level_values(level)でレベルを確認できます。レベル数を確認するにはdf.index.nlevelsを使います。names属性には各レベルに割り当てられた名前が一覧表示されます。名前はdf.index.set_names(['level0', 'level1'])で設定します。
import pandas as pd
df_flat = pd.DataFrame({
'country': ['USA', 'USA', 'UK', 'UK'],
'year': [2022, 2023, 2022, 2023],
'gdp': [25000, 26000, 3100, 3200]
})
df = df_flat.set_index(['country', 'year'])
print('Number of levels:', df.index.nlevels)
print('Level names:', df.index.names)
print('Level 0 values:', df.index.get_level_values(0).tolist())
print('Level 1 values:', df.index.get_level_values(1).tolist())
print('Unique level 0:', df.index.get_level_values('country').unique().tolist())列にMultiIndexを設定する
MultiIndexは列にも適用でき、列ラベルの階層を作成できます。これは、ピボット形式のレイアウトでカテゴリごとに複数の指標を格納する場合によく使われます。たとえば、(revenue, Q1)、(revenue, Q2)、(cost, Q1)、(cost, Q2)のように表します。行にアクセスする場合と同じく、タプルを使ってMultiIndexの列にアクセスできます。pd.MultiIndex.from_productで列のMultiIndexを作成し、df.columnsに代入してください。
import pandas as pd
import numpy as np
# Create a DataFrame with MultiIndex columns
metrics = ['revenue', 'cost']
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
col_index = pd.MultiIndex.from_product([metrics, quarters], names=['metric', 'quarter'])
data = np.random.randint(50, 200, size=(3, 8))
df = pd.DataFrame(data, columns=col_index, index=['USA', 'UK', 'DE'])
df.index.name = 'country'
print(df)GroupBy集計後のMultiIndex
groupby([col1, col2]).agg(...)を呼び出すと、結果のDataFrameでは行にMultiIndexが設定されます(2つのgroupbyキーが2つのインデックスレベルになります)。また、複数の指標を集計した場合は、列にもMultiIndexが設定されることがあります。日常的なデータ分析でMultiIndexに出会う最も一般的な場面はこれです。groupbyの結果を扱うには、その移動方法を理解することが不可欠です。
import pandas as pd
import seaborn as sns
tips = sns.load_dataset('tips')
# Two-key groupby creates a MultiIndex on rows
result = tips.groupby(['day', 'time'])['total_bill'].agg(['mean', 'count'])
print(result)
print('\nIndex type:', type(result.index).__name__)
print('Index names:', result.index.names)レベルを入れ替えて並べ替える
2つのインデックスレベルを入れ替えるにはdf.swaplevel()を使い、すべてのレベルの順序を変更するにはdf.reorder_levels([...])を使います。内側のレベルを先にスライスしたい場合や、2つのDataFrameでインデックスレベルの順序が異なり、マージ前に揃える必要がある場合に、レベルの並べ替えが役立ちます。並べ替えた後は、効率的にスライスできる辞書順を復元するため、必ずsort_index()を呼び出してください。
import pandas as pd
import seaborn as sns
tips = sns.load_dataset('tips')
result = tips.groupby(['day', 'time'])['total_bill'].mean()
print('Original levels:', result.index.names)
# Swap so time is the outer level
swapped = result.swaplevel().sort_index()
print('\nSwapped levels:', swapped.index.names)
print(swapped.head())MultiIndexを確認して並べ替える
MultiIndexのスライスは、インデックスが辞書順にソートされている場合にのみ効率的に実行できます。インデックスがソートされているかどうかはdf.index.is_monotonic_increasingで確認してください。Falseが返された場合は、df.sort_index()でソートします。ソートされていないMultiIndexでスライス操作を行うとPerformanceWarningが発生し、一部の特殊なケースでは誤った結果が返ることがあります。MultiIndexを作成または変更した後は、必ずソートしてください。
import pandas as pd
# Create an unsorted MultiIndex deliberately
tuples = [('B', 2), ('A', 1), ('B', 1), ('A', 2)]
mi = pd.MultiIndex.from_tuples(tuples, names=['letter', 'num'])
df = pd.DataFrame({'value': [10, 20, 30, 40]}, index=mi)
print('Is sorted:', df.index.is_monotonic_increasing)
print('Before sorting:')
print(df)
df_sorted = df.sort_index()
print('\nAfter sorting:')
print(df_sorted)
print('Is sorted:', df_sorted.index.is_monotonic_increasing)MultiIndexを列に戻す
df.reset_index()を呼び出すと、すべてのインデックスレベルが通常の列に戻り、DataFrameのインデックスは単純な整数のRangeIndexになります。これは、groupby集計の後によく使われるパターンです。MultiIndexでグループ化した集計結果を作成し、その後インデックスをリセットして、以降のPandas操作やマージ、CSVへのエクスポートに適したフラットなDataFrameにします。2レベルのインデックスのうち1つだけをリセットするには、reset_index(level='name')を使用します。
import pandas as pd
import seaborn as sns
tips = sns.load_dataset('tips')
result = tips.groupby(['day', 'time'])['total_bill'].mean()
print('MultiIndex result:')
print(result.head(4))
# Flatten back to a regular DataFrame
flat = result.reset_index()
print('\nFlattened DataFrame:')
print(flat.head(4))
print('Index type:', type(flat.index).__name__)MultiIndexを使う場面
データに自然な階層構造がある場合は、MultiIndexを使用します。たとえば、1日未満の粒度を持つ時系列(日時 + 時間)、パネルデータ(エンティティ + 期間)、入れ子になったグループ化(国 + 地域 + 都市)などです。単純な2列のグループキーで、個別の列を持つフラットなDataFrameのほうが同じように読みやすい場合は、MultiIndexを避けてください。データにアクセスするためだけに常にreset_index()を呼び出しているなら、ワークフローにおいてMultiIndexが価値を追加できていないサインです。
理解度チェック
このレッスンで学んだMultiIndexの作成について理解度を確認しましょう。
レッスンのまとめ
このレッスンでは、MultiIndexがタプルを使用して階層的な行(または列)ラベルを提供すること、from_tuples、from_product、または複数列に対するset_indexで作成できること、効率的なスライスのために常にソートしておくことを学びました。次は、.loc、タプル、スライス、IndexSliceヘルパーを使ってMultiIndexからデータを選択する方法を学びます。
よくある質問
「MultiIndexの作成」レッスンは無料ですか?
はい。「MultiIndexの作成」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Pandas & NumPy Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Pandas & NumPy Academyコースには全4レッスンが含まれています。
「MultiIndexの作成」で何を学びますか?
pd.MultiIndex.from_tuplesまたは複数列へのset_indexで階層型の行インデックスを作成し、そのレベルを確認します。 ブラウザで直接実行するハンズオンコードでPandas & NumPy Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Pandas & NumPy Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのPandas & NumPy Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「MultiIndexの作成」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このPandas & NumPy Academyレッスンでコードを書いて実行できますか?
はい。すべてのPandas & NumPy Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。