Pandasのマルチインデックスは、データ分析の際に非常に強力なツールとなります。この記事では、マルチインデックスの基本的な作成方法から、列名の変更、データの取得、そして不要なインデックスの削除方法まで、詳しく解説します。
マルチインデックスの基本
マルチインデックスとは、データフレームやシリーズのインデックスが複数のレベルを持つことを指します。これにより、階層的なデータ構造を簡単に扱うことができます。
import pandas as pd
arrays = [['A', 'A', 'B', 'B'], [1, 2, 1, 2]]
df = pd.DataFrame(np.random.rand(4, 2), index=arrays)
print(df)
0 1
A 1 0.437587 0.891773
2 0.963663 0.383442
B 1 0.791725 0.528895
2 0.568045 0.925597
このコードは、2つのレベルを持つマルチインデックスのデータフレームを作成します。
マルチインデックスの列名の変更
マルチインデックスの列名を変更するには、names
属性を使用します。
df.index.names = ['key1', 'key2']
print(df)
0 1
key1 key2
A 1 0.437587 0.891773
2 0.963663 0.383442
B 1 0.791725 0.528895
2 0.568045 0.925597
このコードにより、マルチインデックスの列名がkey1
とkey2
に変更されます。
マルチインデックスでのデータの取得
マルチインデックスのデータフレームからデータを取得するには、インデックスのタプルを使用します。
print(df.loc[('A', 1)])
0 0.437587
1 0.891773
Name: (A, 1), dtype: float64
このコードは、key1
がA
で、key2
が1
のデータを取得します。
マルチインデックスの削除(シングルインデックスへの変更)
Pandasのデータフレームにおいて、マルチインデックスを持つ列を扱う際、その列名を削除(シングルインデックスの形式に変更)することがよくあります。特に、データの可視化やエクスポート時に、列名をシンプルにしたい場合にこの方法が役立ちます。
reset_index
を使用する方法
reset_index
メソッドを使用すると、マルチインデックスを通常の列に変換し、新しいデフォルトのインデックスを持つデータフレームを取得できます。
例として、以下のマルチインデックスを持つデータフレームを考えます:
import pandas as pd
arrays = [['A', 'A', 'B', 'B'], [1, 2, 1, 2]]
df_tmp = pd.DataFrame(np.random.rand(4, 2), index=arrays)
print(df_tmp)
0 1
A 1 0.071036 0.087129
2 0.020218 0.832620
B 1 0.778157 0.870012
2 0.978618 0.799159
このデータフレームにreset_index
を適用すると、以下のようになります:
df_reset = df_tmp.reset_index()
print(df_reset)
level_0 level_1 0 1
0 A 1 0.437587 0.891773
1 A 2 0.963663 0.383442
2 B 1 0.791725 0.528895
3 B 2 0.568045 0.925597
この方法は、マルチインデックスを保持しながら、そのインデックスの値を通常の列として取得したい場合に便利です。
リスト内包表記を使用する方法
マルチインデックスの列名使用してシングルインデックスの形式に変更するには以下のようなリスト内包表記で対応できます:
df_tmp.columns = ["_".join(pair) for pair in df_tmp.columns]
このコードは、マルチインデックスの各ペア(例:('A', 1)
)をアンダースコア(_
)で結合して、シングルインデックスの列名(例:A_1
)に変更します。
少し難しいのでこのコードの詳細な動作を以下に説明します:
df_tmp.columns
:df_tmp
の現在の列名(マルチインデックス)を取得します。これは、タプルのリストとして返されます。例:[('A', 1), ('A', 2), ...]
"_".join(pair) for pair in df_tmp.columns
:- リスト内包表記を使用して、
df_tmp.columns
の各タプル(マルチインデックスのペア)を順番に取り出します。 "_".join(pair)
は、タプルの各要素をアンダースコア(_
)で結合します。この操作により、タプル('A', 1)
は文字列'A_1'
に変換されます。
- リスト内包表記を使用して、
- 結果:
- 最終的に、マルチインデックスの列名がシングルインデックスの形式に変更されます。例:
A_1
,A_2
, …
- 最終的に、マルチインデックスの列名がシングルインデックスの形式に変更されます。例:
NamedAgg
を使用する方法
PandasのNamedAgg
は、集約操作を行う際に新しい列名を指定するためのツールです。これにより、マルチインデックスの列名をシングルインデックスの形式に変更することができます。
例として、以下のようなデータフレームを考えます:
import pandas as pd
df = pd.DataFrame({
'A': ['foo', 'foo', 'foo', 'bar', 'bar'],
'B': ['one', 'one', 'two', 'two', 'one'],
'C': [1, 2, 3, 4, 5],
'D': [10, 20, 30, 40, 50]
})
print(df)
A B C D
0 foo one 1 10
1 foo one 2 20
2 foo two 3 30
3 bar two 4 40
4 bar one 5 50
このデータフレームに対して、A
とB
でグループ化し、C
とD
の平均を計算する場合、以下のようにNamedAgg
を使用します:
result = df.groupby(['A', 'B']).agg(
avg_C=pd.NamedAgg(column='C', aggfunc='mean'),
avg_D=pd.NamedAgg(column='D', aggfunc='mean')
).reset_index()
print(result)
A B avg_C avg_D
0 bar one 5.0 50.0
1 bar two 4.0 40.0
2 foo one 1.5 15.0
3 foo two 3.0 30.0
上記の通りavg_C
とavg_D
という新しい列名で、それぞれC
とD
の平均値が計算されます。
なお、groupbyからのaggについては以下に詳しく紹介していますので、こちらをご参照ください。
Pandasのagg関数は強力なデータ集計のツールです。この記事では、agg関数の基本的な使い方から、apply関数との違い、条件に基づくカウント方法、そしてグループごとの最初の値の取得方法まで、具体的なコード例とともに解説します。 […]
以上、この記事ではPandasのマルチインデックスに関する基本的な操作を解説しました。マルチインデックスは、階層的なデータ構造を効率的に扱うための強力なツールです。これらの知識を活用して、データ分析の幅をさらに広げてください。