それで、MultiIndexなしでDataFrame.groupbyを使用してサブサンプリング/クロスセクションを実行できることを学びました。
一方、DataFrameにMultiIndexがある場合でも、DataFrame.groupbyを使用してサブサンプリング/クロスセクションを実行する必要があります。
では、印刷時の階層の非常に役立つ、かなりの表示とは別に、MultiIndexは何に適していますか?
pandas 0.4リリースで、階層型インデックス(「マルチレベル」インデックスとも呼ばれる)が導入されました。
これは、特により高次元のデータを操作するために、いくつかの非常に高度なデータ分析と操作への扉を開きます。本質的には、たとえば、2次元の表構造(DataFrame)に任意の高次元のデータを効果的に格納および操作することができます。
次のようにMultiIndex
を使用してデータフレームを構築することを想像してください:
import pandas as pd
import numpy as np
np.arrays = [['one','one','one','two','two','two'],[1,2,3,1,2,3]]
df = pd.DataFrame(np.random.randn(6,2),index=pd.MultiIndex.from_tuples(list(Zip(*np.arrays))),columns=['A','B'])
df # This is the dataframe we have generated
A B
one 1 -0.732470 -0.313871
2 -0.031109 -2.068794
3 1.520652 0.471764
two 1 -0.101713 -1.204458
2 0.958008 -0.455419
3 -0.191702 -0.915983
このdf
は、単純に2次元のデータ構造です
df.ndim
2
しかし、出力を3次元のデータ構造として見ると想像できます。
one
と1
データあり-0.732470 -0.313871
。one
と2
データあり-0.031109 -2.068794
。one
と3
データあり1.520652 0.471764
。別名:「2次元の表構造で任意の高次元のデータを効果的に格納および操作する」
これは単なる「きれいなディスプレイ」ではありません。これで、階層インデックスが作成されたため、データを簡単に取得できるという利点があります。
例えば。
In [44]: df.ix["one"]
Out[44]:
A B
1 -0.732470 -0.313871
2 -0.031109 -2.068794
3 1.520652 0.471764
「1」に属するデータのグループにのみ新しいデータフレームを提供します。
そして、これを行うことでデータ選択をさらに絞り込むことができます:
In [45]: df.ix["one"].ix[1]
Out[45]:
A -0.732470
B -0.313871
Name: 1
そしてもちろん、特定の値が必要な場合は、例を示します:-
In [46]: df.ix["one"].ix[1]["A"]
Out[46]: -0.73247029752040727
したがって、(上記の例に示されている2つのインデックスに加えて)さらに多くのインデックスがある場合、groupby
を必要とせずに、基本的にドリルダウンして、本当に関心のあるデータセットを選択できます。
データフレームから断面(行または列)を取得することもできます...
行ごと:-
In [47]: df.xs('one')
Out[47]:
A B
1 -0.732470 -0.313871
2 -0.031109 -2.068794
3 1.520652 0.471764
列ごと:-
In [48]: df.xs('B', axis=1)
Out[48]:
one 1 -0.313871
2 -2.068794
3 0.471764
two 1 -1.204458
2 -0.455419
3 -0.915983
Name: B
@Calvin Chengによる素晴らしい投稿ですが、私もこれを試してみようと思いました。
マルチインデックスを使用する場合:
なぜ(あなたの中心的な質問)-少なくともこれらはIMOの最大の利点です:
例:
_ Dollars Units
Date Store Category Subcategory UPC EAN
2018-07-10 Store 1 Alcohol Liqour 80480280024 154.77 7
Store 2 Alcohol Liqour 80480280024 82.08 4
Store 3 Alcohol Liqour 80480280024 259.38 9
Store 1 Alcohol Liquor 80432400630 477.68 14
674545000001 139.68 4
Store 2 Alcohol Liquor 80432400630 203.88 6
674545000001 377.13 13
Store 3 Alcohol Liquor 80432400630 239.19 7
674545000001 432.32 14
Store 1 Beer Ales 94922755711 65.17 7
702770082018 174.44 14
736920111112 50.70 5
Store 2 Beer Ales 94922755711 129.60 12
702770082018 107.40 10
736920111112 59.65 5
Store 3 Beer Ales 94922755711 154.00 14
702770082018 137.40 10
736920111112 107.88 12
Store 1 Beer Lagers 702770081011 156.24 12
Store 2 Beer Lagers 702770081011 137.06 11
Store 3 Beer Lagers 702770081011 119.52 8
_
1)店舗間の売上高を簡単に比較したい場合は、df.unstack('Store')
を使用してすべてを並べて並べることができます。
_ Dollars Units
Store Store 1 Store 2 Store 3 Store 1 Store 2 Store 3
Date Category Subcategory UPC EAN
2018-07-10 Alcohol Liqour 80480280024 154.77 82.08 259.38 7 4 9
Liquor 80432400630 477.68 203.88 239.19 14 6 7
674545000001 139.68 377.13 432.32 4 13 14
Beer Ales 94922755711 65.17 129.60 154.00 7 12 14
702770082018 174.44 107.40 137.40 14 10 10
736920111112 50.70 59.65 107.88 5 5 12
Lagers 702770081011 156.24 137.06 119.52 12 11 8
_
2)複数の列で簡単に計算することもできます。たとえば、_df['Dollars'] / df['Units']
_は、複数の操作を行わないすべてのストアについて、各ストアのドルをその単位で割ります。
_Store Store 1 Store 2 Store 3
Date Category Subcategory UPC EAN
2018-07-10 Alcohol Liqour 80480280024 22.11 20.52 28.82
Liquor 80432400630 34.12 33.98 34.17
674545000001 34.92 29.01 30.88
Beer Ales 94922755711 9.31 10.80 11.00
702770082018 12.46 10.74 13.74
736920111112 10.14 11.93 8.99
Lagers 702770081011 13.02 12.46 14.94
_
3)次に、特定の行のみにフィルタリングする場合は、
_df[(df[col1] == val1) and (df[col2] == val2) and (df[col3] == val3)]
_
形式、代わりに.xsまたは.queryを使用できます(これらは通常のdfで機能しますが、あまり役に立ちません)。構文は代わりに次のようになります。
_df.xs((val1, val2, val3), level=(col1, col2, col3))
_
より多くの例がこれにあります チュートリアルノート まとめました。