import pandas as pd
import numpy as np
Pythonで、マルチインデックスのデータフレームから指定したデータを取得する方法です。
使用するのは、Pythonのpandasライブラリのxsメソッドです。
マルチインデックスとは、複数の列をインデックスとして適用させることができる、データフレームの仕組みのことです。
data = np.random.randint(150, 400,(8, 3))
idx = [['A店', 'A店', 'A店', 'B店', 'B店', 'C店', 'C店', 'C店'],
['りんご', 'バナナ', 'もも', 'りんご', 'もも', 'りんご', 'バナナ', 'もも'],
['パック', '箱', '箱', '箱', 'パック', 'パック', '箱', 'パック']]
col = ['10/1', '10/2', '10/3']
df = pd.DataFrame(data=data, index=idx, columns=col)
df.index.names = ['店名', '商品名', '包装']
df
10/1 | 10/2 | 10/3 | |||
---|---|---|---|---|---|
店名 | 商品名 | 包装 | |||
A店 | りんご | パック | 216 | 188 | 247 |
バナナ | 箱 | 178 | 268 | 198 | |
もも | 箱 | 335 | 230 | 299 | |
B店 | りんご | 箱 | 306 | 300 | 389 |
もも | パック | 250 | 232 | 151 | |
C店 | りんご | パック | 247 | 293 | 355 |
バナナ | 箱 | 300 | 367 | 315 | |
もも | パック | 257 | 286 | 340 |
このようなデータフレームを使用します。
店名、商品名、包装がマルチインデックスになっています。
df.xs('B店',level=0)
10/1 | 10/2 | 10/3 | ||
---|---|---|---|---|
商品名 | 包装 | |||
りんご | 箱 | 306 | 300 | 389 |
もも | パック | 250 | 232 | 151 |
マルチインデックスでは、外側の階層から0,1,-1と数えます。
そして、この数字をlevelという引数で指定して、各データを取得することができます。
つまり、B店のデータを取得したい場合にはこのような記述になります。
第一引数に取得したい値、第二引数でlevelで階層を指定します。
実行します。
B店のデータを取得することができました。
なお、一番外側の階層を指定する場合のみ、引数levelは省略できます。
df.xs('りんご', level=1)
10/1 | 10/2 | 10/3 | ||
---|---|---|---|---|
店名 | 包装 | |||
A店 | パック | 216 | 188 | 247 |
B店 | 箱 | 306 | 300 | 389 |
C店 | パック | 247 | 293 | 355 |
次に、内側の階層を指定してデータを取得してみましょう。
1つ内側の商品名を指定するので、1とします。
実行します。
各店舗における、りんごのデータを取得することができました。
df.xs('A店', level='店名')
10/1 | 10/2 | 10/3 | ||
---|---|---|---|---|
商品名 | 包装 | |||
りんご | パック | 216 | 188 | 247 |
バナナ | 箱 | 178 | 268 | 198 |
もも | 箱 | 335 | 230 | 299 |
なお、引数levelには、数字ではなく階層名を指定することもできます。
実行します。
A店のデータを取得することができました。
df.xs(['A店', 'パック'], level=[0, '包装'])
10/1 | 10/2 | 10/3 | |
---|---|---|---|
商品名 | |||
りんご | 216 | 188 | 247 |
また、値と階層を複数指定することもできます。
それぞれ引数にリストで指定して、実行します。
データを取得することができました。
df.xs('りんご', level='商品名')['10/2']
店名 包装
A店 パック 188
B店 箱 300
C店 パック 293
Name: 10/2, dtype: int64
追加でカラムを指定をすることもできます。
角括弧でカラム名を追加して実行します。
10月2日における、りんごのデータを取得することができました。
df.xs('10/3', axis=1)
店名 商品名 包装
A店 りんご パック 247
バナナ 箱 198
もも 箱 299
B店 りんご 箱 389
もも パック 151
C店 りんご パック 355
バナナ 箱 315
もも パック 340
Name: 10/3, dtype: int64
カラムのみを指定する場合には、axis=1を指定します。
実行します。
10月3日におけるデータを取得できました。
関連メソッド
【毎日Python】Pandasのデータフレームのインデックスを取得する方法|index属性
【毎日Python】Pythonでインデックスから行番号、カラムから列番号を取得する方法|pandas.index.get_loc