pandas の stack、unstack メソッドは名前を見ただけではその機能が想像つきません。
書籍 「Pythonによるデータ分析入門」 の説明を見ると
stack : 列から行へのピボット
unstack : 行から列へのピボット
unstack : 行から列へのピボット
と書いてありますが、やっぱりよく判りません。
Series で使ってみる
Series で使えるのは unstack のみです。また、インデックスが階層化されている場合にかぎり有効です。
データ
階層型インデックスの Series に、2次元の情報をを持たせます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from pandas import Series ss = Series([1,2,3,4,5], index=[['AA','AA','AA','BB','BB'], ['test1','test2','test3','test1','test3']]) #---------------------------- # AA test1 1 # test2 2 # test3 3 # BB test1 4 # test3 5 #---------------------------- ↑ ↑ インデックスが2階層 |
unstack 実行
unstack すると表形式になります。
1 2 3 4 5 6 |
ss.unstack() #---------------------------- # test1 test2 test3 ← インデックスからカラムへ移動してきた # AA 1 2 3 # BB 4 NaN 5 #---------------------------- |
内側のインデックス(test1 、test2 、test3)がカラムへ移動しました。それにあわせて、データも並べ替えられています。
つまり、unstack は、行方向のデータを列方向に動かしてくれます。
unstack の引数
移動するインデックスは引数で指定できます。外側のインデックスを移動したければ 0 を、内側のインデックスを移動したければ 1 を指定します。
1 2 3 4 5 6 7 |
ss.unstack(0) #---------------------------- # AA BB ← インデックスからカラムへ移動してきた # test1 1 4 # test2 2 NaN # test3 3 5 #---------------------------- |
DataFrame で stack を使ってみる
データ
表形式のデータ。
1 2 3 4 5 6 7 8 9 10 |
from pandas import DataFrame df=DataFrame([[1,2,3],[4,np.nan,5]], columns=['test1','test2','test3'], index=['AA','BB']) #---------------------------- # test1 test2 test3 # AA 1 2 3 # BB 4 NaN 5 #---------------------------- |
stack 実行
stack すると、階層型インデックスの Series になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
df.stack() #---------------------------- # AA test1 1 # test2 2 # test3 3 # BB test1 4 # test3 5 #---------------------------- ↑ カラムからインデックスへ移動してきた # # デフォルトでは、NaN が除去されます。 # 残したければ dropna=False を指定します。 # df.stack(dropna=False) #---------------------------- # AA test1 1 # test2 2 # test3 3 # BB test1 4 # test2 NaN # test3 5 #---------------------------- |
stack は、列方向のデータを行方向に並べてくれます。
DataFrame で unstack を使ってみる
データ
インデックスが階層型のデータを準備します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
df=DataFrame([[1,2,3],[4,5,6],[7,np.nan,8],[9,10,11]], columns=['test1','test2','test3'], index=[['AA','AA','BB','BB'],['2014','2015','2014','2015']]) #------------------------------------- # test1 test2 test3 # AA 2014 1 2 3 # 2015 4 5 6 # BB 2014 7 NaN 8 # 2015 9 10 11 #------------------------------------- ↑ ↑ インデックスが2階層 |
unstack 実行
unstack すると内側のインデックスが列へ移動します。
1 2 3 4 5 6 7 |
df.unstack() #------------------------------------- # test1 test2 test3 # 2014 2015 2014 2015 2014 2015 ← インデックスからカラムへ移動してきた # AA 1 4 2 5 3 6 # BB 7 9 NaN 10 8 11 #------------------------------------- |
unstack の引数
移動するインデックスは引数で指定できます。外側のインデックスを移動したければ 0 を、内側のインデックスを移動したければ 1 を指定します。
1 2 3 4 5 6 7 |
df.unstack(0) #------------------------------------- # test1 test2 test3 # AA BB AA BB AA BB ← インデックスからカラムへ移動してきた # 2014 1 7 2 NaN 3 8 # 2015 4 9 5 10 6 11 #------------------------------------- |
stack、unstack を組み合わせ
stack、unstack を組み合わせれば、好きなように形を変形できます。
1 2 3 4 5 6 7 8 |
df.stack().unstack(0).unstack(0) #------------------------------------- # AA BB # 2014 2015 2014 2015 # test1 1 4 7 9 # test2 2 5 NaN 10 # test3 3 6 8 11 #------------------------------------- |
ちなみに、上の結果は転置行列 df.T と同じです。