PandasにおけるDataFrameのシェイプ変更のメソッドである、 pivot、pivot_table、melt、stack、wide_to_longについて、これらをまとめて図解してみました。
実例
import pandas as pd import io df = pd.read_csv(io.StringIO(""" year,season,num 2010,春,4 2010,夏,1 2010,秋,2 2011,春,3 2011,夏,4 2012,春,1 2012,冬,2 """ )) ## pivot _ = df.pivot(index='year', columns='season', values='num') _ _.index ## pivot_table import numpy as np _ = pd.pivot_table(data=df,index='year', columns='season', aggfunc=len) # lenは欠損値の場合カウントしないので注意。 _ type(_) # pandas.core.frame.DataFrame _ = pd.pivot_table(data=df,index=['year'], columns=['season'], aggfunc=[np.max,np.min,np.mean]) _ type(_) # pandas.core.frame.DataFrame type(_.index) type(_.columns) # -> pandas.core.indexes.multi.MultiIndex ※ index、columns、aggfuncどれかに配列を指定した場合、MultiIndexになる。 # columnsがMultiIndexの場合(でも)、DataFrame.columnsに直接、件数を合わせた配列を代入してやれば、通常のインデックスになる↓ _.columns = ['_'.join(i) for i in _.columns] _ type(_.columns) ## df = pd.read_csv(io.StringIO(""" year,春,夏,秋,冬 2010,1,2,3,4 2011,5,6,7,8 2012,9,10,11,12 """ )) ## melt _ = df.melt(id_vars='year', var_name='季節', value_name='値') _ ## stack _ = df.stack() type(_) # -> pandas.core.series.Series _.index ## wide_to_long df = pd.read_csv(io.StringIO(""" id,A111,A222,B111,C222,X 0,1,2,3,4,5 1,2,4,6,8,10 2,3,6,9,12,15 """ )) pd.wide_to_long(df,stubnames=['A','B','C'], i='id',j='threechars') # stubnamesに「_」を使う時は注意
ひとつずつ分解した例
1-1. サンプルインプットデータ1
In [298]: ...: ...: df = pd.read_csv(io.StringIO(""" ...: year,season,num ...: 2010,春,4 ...: 2010,夏,1 ...: 2010,秋,2 ...: 2011,春,3 ...: 2011,夏,4 ...: 2012,春,1 ...: 2012,冬,2 ...: """ ))
1-2. pivot
In [299]: ...: _ = df.pivot(index='year', columns='season', values='num') ...: _ Out[299]: season 冬 夏 春 秋 year 2010 NaN 1.0 4.0 2.0 2011 NaN 4.0 3.0 NaN 2012 2.0 NaN 1.0 NaN In [300]:
1-3. pivot_table
pivot_tableは集計。 位置付けからすると、重複データを扱える。
In [300]: ...: import numpy as np ...: _ = pd.pivot_table(data=df,index='year', columns='season', aggfunc=len) # lenは欠損値の場合カウントしないので注意。 ...: _ Out[300]: num season 冬 夏 春 秋 year 2010 NaN 1.0 1.0 1.0 2011 NaN 1.0 1.0 NaN 2012 1.0 NaN 1.0 NaN
2-1. サンプルインプットデータ2
In [301]: ...: ...: df = pd.read_csv(io.StringIO(""" ...: year,春,夏,秋,冬 ...: 2010,1,2,3,4 ...: 2011,5,6,7,8 ...: 2012,9,10,11,12 ...: """ )) ...: In [302]:
## 2-2. melt
In [302]: ...: _ = df.melt(id_vars='year', var_name='季節', value_name='値') ...: _ ...: Out[302]: year 季節 値 0 2010 春 1 1 2011 春 5 2 2012 春 9 3 2010 夏 2 4 2011 夏 6 5 2012 夏 10 6 2010 秋 3 7 2011 秋 7 8 2012 秋 11 9 2010 冬 4 10 2011 冬 8 11 2012 冬 12
2-3. stack
In [303]: ...: _ = df.stack() ...: In [304]: _ Out[304]: 0 year 2010 春 1 夏 2 秋 3 冬 4 1 year 2011 春 5 夏 6 秋 7 冬 8 2 year 2012 春 9 夏 10 秋 11 冬 12 dtype: int64 In [305]:
2-4. wide_to_long
In [305]: ...: ...: df = pd.read_csv(io.StringIO(""" ...: id,A111,A222,B111,C222,X ...: 0,1,2,3,4,5 ...: 1,2,4,6,8,10 ...: 2,3,6,9,12,15 ...: """ )) In [306]: In [306]: pd.wide_to_long(df,stubnames=['A','B','C'], i='id',j='threechars') Out[306]: X A B C id threechars 0 111 5 1 3.0 NaN 222 5 2 NaN 4.0 1 111 10 2 6.0 NaN 222 10 4 NaN 8.0 2 111 15 3 9.0 NaN 222 15 6 NaN 12.0