LoginSignup
1
2

pandasのマルチインデックスのチートシート

Posted at

pandasでgroupby()pivot_table()を使うと、Multi indexを持つ多層のテーブルが出てくることがよくあります。分かりやすいし便利機能かと思いきや、解除や結合ができないためにこの操作で時間を溶かすことがあまりにも多いので、よく使う方法をまとめておきます。

導入

今回はかの有名なタイタニック号のデータ(signateより取得)を使って作成した、マルチインデックスを持つピボットテーブルをサンプルとして説明していきます。

使用するテーブルとコードは以下をご覧ください。

import pandas as pd
df = pd.read_csv("train.tsv", sep="\t") # 学習用データ読み込み

avg = pd.pivot_table(df, index='pclass', columns='sex', values = ['age', 'fare'])    # チケットクラス・性別ごとの年齢・料金の平均値 

sex
pclass
age

female


male
fare

female


male
1 33.52 38.08 98.23 79.28
2 28.07 30.29 22.67 20.93
3 21.06 26.87 16.86 13.45

そもそもマルチインデックスの形って?

マルチインデックスの各部分の名称は通常のデータフレームの場合と異なります。columnsという概念がMultiIndexに代わるようなイメージ(下図参照)。
image.png

実際にcolumnsメソッドやindexメソッドを使って結果を確認してみると以下のようになります。

# columnsを確認
print(avg.columns)

# 出力
MultiIndex([( 'age', 'female'),
            ( 'age',   'male'),
            ('fare', 'female'),
            ('fare',   'male')],
           names=[None, 'sex'])
# indexを確認
print(avg.index)

# 出力
Index([1, 2, 3], dtype='int64', name='pclass')

マルチインデックスのチートシート

1. マルチインデックスからカラムを取り出す

マルチインデックスのカラムの層は、levelで指定することができます。下の図の例から分かるように、levelは0から始まり、上段に進むとlevelが増えていきます。
image.png

以下のコードで各レベルのカラムを取得することができます。

# level0のカラム名を表示
print(avg.columns.droplevel(0))

# 出力
Index(['female', 'male', 'female', 'male'], dtype='object', name='sex')

2. マルチインデックスのインデックス編集

2-1. インデックスの解除

通常のデータフレームと同じく、以下コードでインデックスの解除ができます。ここで解除されるのはインデックスのみで、マルチインデックス構造自体は解除されないので注意です。 解除されたインデックスについていた名前は上段のカラム名となります(drop=Trueオプションをつけると削除されます)。

# インデックスの解除
avg.reset_index()
sex pclass


female
age
male

female
fare
male
0 1.00 33.52 38.08 98.23 79.28
1 2.00 28.07 30.29 22.67 20.93
2 3.00 21.06 26.87 16.86 13.45

2-2. インデックス列に名前をつける

こちらも通常のデータフレームと同じく、インデックスの列に名前をつけることができます。ここでも命名されるのはインデックス列のみで、マルチインデックス構造自体には変更がありません。

# 上記の方法で既存のインデックスを解除
reset_index_avg = avg.reset_index()
# 名無しのインデックスに'id'という名前をつける
reset_index_avg.index.name = 'id'
reset_index_avg

sex
id
pclass




female

age
male


female

fare
male
0 1.00 33.52 38.08 98.23 79.28
1 2.00 28.07 30.29 22.67 20.93
2 3.00 21.06 26.87 16.86 13.45

3. マルチインデックスのテーブルを通常のデータフレームに変換

マルチインデックスの多段構成のデータフレームだと、結合やカラムの抽出に難があるので、通常のデータフレームに直したいという時に便利な方法があります。

まずは抽出したいlevelのカラムを取得し、それをデータフレームのカラムとして指定します。その上で必要があればインデックスを解除します。

avg_level0 = avg.copy()
# level0のカラムだけ抽出
avg_level0.columns = avg.columns.droplevel(0)
# 設定されているインデックスを解除
avg_level0.reset_index(inplace=True)
avg_level0
sex pclass female male female male
0 1.00 33.52 38.08 98.23 79.28
1 2.00 28.07 30.29 22.67 20.93
2 3.00 21.06 26.87 16.86 13.45

このままだとlevel1のカラム情報が失われてしまい、female・maleというカラムが二つずつある状態になってしまうので、区別できるようにカラム名を付け直すと以下のようになります(※この操作は不要であれば実行しなくても大丈夫です!)。

avg_level0.set_axis(['pclass', 'age_female', 'age_male', 'fare_female', 'fare_male'], axis=1)
pclass age_female age_male fare_female fare_male
0 1.00 33.52 38.08 98.23 79.28
1 2.00 28.07 30.29 22.67 20.93
2 3.00 21.06 26.87 16.86 13.45

以上の手順で、マルチインデックス構成だった時の情報をほとんど失わずに通常のデータフレームを作る ことができます。

4. マルチインデックスを持つテーブル同士の結合

マルチインデックスを持つテーブルは基本的に結合処理ができません。しかし、マルチインデックスの層構造(=level)が同じテーブル同士であれば結合が可能 です。

例えば、以下の例のようにavgテーブルとマルチインデックスのlevelが等しいavg2テーブルを用意した場合のことを考えます。

avg2 = pd.pivot_table(df, index='pclass', columns='embarked', values = ['age', 'fare'])
avg2

emberked
pclass

C


Q

age
S


C


Q

fare
S

1 36.06 nan 35.08 105.91 nan 79.15
2 21.75 30.00 30.10 26.04 12.35 21.26
3 21.72 27.64 25.81 11.55 9.31 16.03

このavg, avg2テーブルたちをそれぞれのインデックスをキーとして結合を行うと以下のように二つのテーブルがそのまま横並びになったようなテーブルを作ることができます。

pd.merge(avg, avg2, left_index=True, right_index=True, how='left')






pclass



female
age

male



female
fare

male




C




Q
age


S




C




Q
fare


S
1 33.52 38.08 98.23 79.28 36.06 nan 35.08 105.91 nan 79.15
2 28.07 30.29 22.67 20.93 21.75 30.00 30.10 26.04 12.35 21.26
3 21.06 26.87 16.86 13.45 21.72 27.64 25.81 11.55 9.31 16.03

ここではインデックスを結合キーとしましたが、マルチインデックスのタプルをキーとして結合することも可能です。

最後に 

もうマルチインデックスは怖くない(はず)!
マルチインデックスに関する小技やよく使う処理などが他にもあればコメントいただけたらと思います。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2