1.概要
groupby
メソッドを使ってデータをまとめると、マルチインデックスを持ったDataFrameのデータが出てくることがよくあるが、マルチインデックスのデータの取り扱いになれていなく操作がわからなくなることが多発。そこでいったん自分なりに整理した。
2.マルチインデックス・マルチカラムのDataFrame準備
- サンプルデータ+
groupby
+agg
メソッド
カラム(col1
,col2
,col3
)ごとに合計値(sum
)、最大値(max
)、最小値(min
)をまとめる。
⇒マルチインデックスとマルチカラムをもつDataFrame
df = pd.DataFrame({'col1':['a','b','c','a','a','b','b','b','c','a'],
'col2':['A','A','A','A','A','B','B','B','B','B'],
'col3':['AA','AA','BB','BB','AA','AA','BB','BB','CC','CC'],
'val1':np.arange(11,21),
'val2':np.arange(21,31)})
grouped = df.groupby(['col1','col2','col3'])
df_multi = grouped.agg([sum,max,min])
df_multi
3.マルチインデックスの操作
- マルチインデックスの操作として、以下を確認。
- マルチインデックスの解除・再マルチインデックス化
- レベルの変更・並び替え
3.1.マルチインデックスの解除
df_multi_reset = df_multi.reset_index()
df_multi_reset
<マルチインデックスに戻す>
- 以下を実行すればOK。
df_multi_reset.set_index(['col1','col2','col3'])
<カラムのマルチ構造を解除?>
- シンプルなコマンドでマルチカラムを解除する方法は見つけられず。。
転置してマルチインデックスと同様の操作をできるようにするか、タプルにするか。。?
<転置する>
df_multi.T
<タプルにする>
df_multi_tplc = df_multi.copy()
df_multi_tplc.columns = df_multi_tplc.columns.values
df_multi_tplc
タプルにすると、シングルカラムと同様に列を選んだりできる。
df_multi_tplc[[('val1', 'sum'),('val2', 'max'),]]
※注'(val1, sum)'
でなく('val1', 'sum')
になる。
タプルからマルチカラムにもどすコードは以下の通り。
df_multi_tplc.columns = pd.MultiIndex.from_tuples(df_multi_tplc.columns)
df_multi_tplc
※columns
をindex
に置き換えれば行についても同様のことができる。
3.2.並び替え
行・列のレベルの入れ替えとレベルごとのデータ並び替えをして、データのまとまりを編集する。
3.2.1.マルチインデックスのレベル入れ替え&ソート
-
df_multi
の列はcol1
内のまとまり→col2
のまとまり→col3
のまとまりというような階層構造になっている。これを逆の構造にする。
df_multi.swaplevel(0,2,axis=0).sort_index(axis=0)
※axis=1
を書かずに、df_multi.swaplevel(0,2).sort_index()
としてもよい、
3.2.2.マルチカラムのレベル入れ替え&ソート
マルチカラムでも同様のことができる。
df_multi.swaplevel(0,1,axis=1).sort_index(axis=1)
4.要素、DataFrameの抽出
以下の赤枠の要素、青枠のDataFrameの抽出をする。
4.1.赤枠要素の抽出
赤枠の「14」は、以下2通りで抽出可能。
df_multi.loc[('a','A','BB'),('val1','min')]
マルチカラム、インデックスを無視して1行2列を抽出するとしてもOK。(左上端0行0列)
df_multi.iloc[1,2]
4.2.青枠の部分DataFrameの抽出
青枠部分は以下で抽出できる。
df_multi.loc[('b','B'),('val2')]
5.マルチインデックスDataFrameのデータ編集
マルチインデックスDataFrameのデータ追加・削除をする。
5.1.データの入力・更新
df_multi_edit =df_multi.copy()
df_multi_edit.loc[('d','D','DD')]=[1,2,3,4,5,6] # (1)行の追加
df_multi_edit.loc[:,('val3','sum')]=[1,2,3,4,5,6,7,8,9] # (2)列の追加
df_multi_edit.loc[('a','A','AA'),('val1','sum')]=100 # (3)値の書き換え
5.2.行・列の削除
df_multi_edit.drop(('val2'),axis=1,inplace=True) #val2列の削除
df_multi_edit.drop(('c','A','BB'),axis=0,inplace=True) #('c','A','BB')行の削除
df_multi_edit
5.3.データの結合
結合させるデータの準備
df_vol4 = pd.DataFrame({('vol4','a'):range(31,40),
('vol4','b'):np.arange(49,40,-1)},
index= [('a', 'A', 'AA'),('a', 'A', 'BB'),('a', 'B', 'CC'), ('b', 'A', 'AA'),
('b', 'B', 'AA'),('b', 'B', 'BB'),('c', 'A', 'BB'),('c', 'B', 'CC'),('d', 'D', 'DD')
])
df_vol4.index = pd.MultiIndex.from_tuples(df_add.index,names=['col1','col2','col3'])
df_vol4.columns = pd.MultiIndex.from_tuples(df_add.columns)
df_vol4
pd.merge(df_multi_edit,df_vol4,on=('col1','col2','col3'),how ='outer')
6.参照資料
以下の資料を勉強しながら記事を書きました。
3.1.マルチインデックスの解除
- pandasのMultiindexの指定・追加・解除・ソート・レベル変更
https://note.nkmk.me/python-pandas-multiindex-set-reset-sort-swap/
- How to do Multi-Column from_tuples?
https://stackoverflow.com/questions/37835508/how-to-do-multi-column-from-tuples
3.2.並び替え
- pandas.DataFrame.swaplevel
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.swaplevel.html
- Swapping/Ordering multi-index columns in pandas
https://stackoverflow.com/questions/40411300/swapping-ordering-multi-index-columns-in-pandas
以上