pandas でデータを操作する時の Tips (前編の続きの中編) です。
環境は Python 2.7.11, pandas 0.20.3 です。
今回扱う内容は以下です。
1. 連結 (concat, append)
pandas.concat は pandas オブジェクトを連結する。DataFrame の list を指定する。デフォルトは axis=0 で縦方向の連結 (積み上げ), axis=1 で横方向の連結となる。 keys を指定することで MultiIndex を振ることができ, 同名の列がある場合に区別できる。
In [1]: import pandas as pd
In [2]: import numpy as np
In [3]: df1 = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [5, 6, 7, 8]}, index=[0, 1, 2, 3])
In [4]: df1
Out[4]:
A B
0 1 5
1 2 6
2 3 7
3 4 8
In [5]: df2 = pd.DataFrame({'A': [9, 10, 11, 12], 'B': [13, 14, 15, 16]}, index=[4, 5, 6, 7])
In [6]: df2
Out[6]:
A B
4 9 13
5 10 14
6 11 15
7 12 16
In [7]: pd.concat([df1, df2])
Out[7]:
A B
0 1 5
1 2 6
2 3 7
3 4 8
4 9 13
5 10 14
6 11 15
7 12 16
In [8]: pd.concat([df1, df2], axis=1)
Out[8]:
A B A B
0 1.0 5.0 NaN NaN
1 2.0 6.0 NaN NaN
2 3.0 7.0 NaN NaN
3 4.0 8.0 NaN NaN
4 NaN NaN 9.0 13.0
5 NaN NaN 10.0 14.0
6 NaN NaN 11.0 15.0
7 NaN NaN 12.0 16.0
In [9]: df3 = pd.DataFrame({'C': [9, 10, 11, 12], 'D': [13, 14, 15, 16]}, index=[0, 1, 2, 3])
In [10]: pd.concat([df1, df3], axis=1)
Out[10]:
A B C D
0 1 5 9 13
1 2 6 10 14
2 3 7 11 15
3 4 8 12 16
In [11]: pd.concat([df1, df2], axis=1, keys=['a', 'b'])
Out[11]:
a b
A B A B
0 1.0 5.0 NaN NaN
1 2.0 6.0 NaN NaN
2 3.0 7.0 NaN NaN
3 4.0 8.0 NaN NaN
4 NaN NaN 9.0 13.0
5 NaN NaN 10.0 14.0
6 NaN NaN 11.0 15.0
7 NaN NaN 12.0 16.0
pandas.DataFrame.append は DataFrame のメソッドとなるので concat よりシンプルに書ける。
In [12]: df1.append(df2)
Out[12]:
A B
0 1 5
1 2 6
2 3 7
3 4 8
4 9 13
5 10 14
6 11 15
7 12 16
In [13]: df1.append(pd.Series([5, 9], index=['A', 'B'], name=4))
Out[13]:
A B
0 1 5
1 2 6
2 3 7
3 4 8
4 5 9
In [14]: df1.append(pd.Series([5, 9], index=['A', 'B']), ignore_index=True)
Out[14]:
A B
0 1 5
1 2 6
2 3 7
3 4 8
4 5 9
2. 結合 (merge, join)
結合は pandas.DataFrame.merge と pandas.DataFrame.join がある。
join メソッドのデフォルトは how=’left’ (左外部結合) である。他に right (右外部結合), outer (完全外部結合), inner (内部結合) が選択できる。
In [15]: df4 = pd.DataFrame({'C': [9, 10, 11, 12], 'D': [13, 14, 15, 16]}, index=[0, 1, 4, 5])
In [16]: df4
Out[16]:
C D
0 9 13
1 10 14
4 11 15
5 12 16
In [17]: df1
Out[17]:
A B
0 1 5
1 2 6
2 3 7
3 4 8
In [18]: df1.join(df4)
Out[18]:
A B C D
0 1 5 9.0 13.0
1 2 6 10.0 14.0
2 3 7 NaN NaN
3 4 8 NaN NaN
In [19]: df1.join(df4, how='right')
Out[19]:
A B C D
0 1.0 5.0 9 13
1 2.0 6.0 10 14
4 NaN NaN 11 15
5 NaN NaN 12 16
In [20]: df1.join(df4, how='inner')
Out[20]:
A B C D
0 1 5 9 13
1 2 6 10 14
In [21]: df1.join(df4, how='outer')
Out[21]:
A B C D
0 1.0 5.0 9.0 13.0
1 2.0 6.0 10.0 14.0
2 3.0 7.0 NaN NaN
3 4.0 8.0 NaN NaN
4 NaN NaN 11.0 15.0
5 NaN NaN 12.0 16.0
3. 適用 (apply)
pandas.DataFrame.apply は DataFrame の各列 (axis=0, デフォルト値) または各行 (axis=1) に対して関数を適用する。
In [22]: df1
Out[22]:
A B
0 1 5
1 2 6
2 3 7
3 4 8
In [23]: df1.apply(np.mean)
Out[23]:
A 2.5
B 6.5
dtype: float64
In [24]: df1.apply(np.mean, axis=1)
Out[24]:
0 3.0
1 4.0
2 5.0
3 6.0
dtype: float64
4. 写像 (map)
pandas.Series.map は Series の値に対して対応する値を map する。対応関係は Series か dict で指定する。以下は gender 列に含まれる ‘f’, ‘m’ を ‘female’, ‘male’ に置き換える例。
In [25]: df_ceo = pd.DataFrame({'name': ['Marissa Mayer', 'Elon Musk', 'Steve Jobs'],'gender': ['f', 'm', 'm']})
In [26]: df_ceo
Out[26]:
gender name
0 f Marissa Mayer
1 m Elon Musk
2 m Steve Jobs
In [27]: df_ceo['gender'].map(pd.Series(['female', 'male'], index=['f', 'm']))
Out[27]:
0 female
1 male
2 male
Name: gender, dtype: object
In [28]: df_ceo['gender'].map({'f': 'female', 'm': 'male'})
Out[28]:
0 female
1 male
2 male
Name: gender, dtype: object
In [29]: df_ceo['name'].map(lambda x : x.replace(' ', ''))
Out[29]:
0 MarissaMayer
1 ElonMusk
2 SteveJobs
Name: name, dtype: object
5. 集約 (aggregate)
pandas.DataFrame.aggregate は全ての列に対して指定した関数で集約する。 agg は alias。
In [30]: df1.agg(['mean', 'var', 'prod'])
Out[30]:
A B
mean 2.500000 6.500000
var 1.666667 1.666667
prod 24.000000 1680.000000
6. グループ化 (groupby)
グループ化は split-apply-combine (分離-適用-統合) のステップを一つ以上含むプロセスで行われる。
- Splitting: 基準に基づきグループに分離する
- Applying: グループごとに独立に関数を適用する
- Combining: 結果を結合する
pandas.DataFrame.groupby はグループ化された GroupBy object を返す。列名以外にも index も指定できる。
In [31]: iris.groupby('species')
Out[31]: <pandas.core.groupby.DataFrameGroupBy object at 0x1068479d0>
GroupBy object に対して集約関数を適用する。
In [32]: iris.groupby('species').size()
Out[32]:
species
setosa 50
versicolor 50
virginica 50
dtype: int64
In [33]: iris.groupby('species').mean()
Out[33]:
sepal_length sepal_width petal_length petal_width
species
setosa 5.006 3.418 1.464 0.244
versicolor 5.936 2.770 4.260 1.326
virginica 6.588 2.974 5.552 2.026
In [34]: iris.groupby('species').var()
Out[34]:
sepal_length sepal_width petal_length petal_width
species
setosa 0.124249 0.145180 0.030106 0.011494
versicolor 0.266433 0.098469 0.220816 0.039106
virginica 0.404343 0.104004 0.304588 0.075433
In [35]: iris.groupby('species').describe()
Out[35]:
petal_length \
count mean std min 25% 50% 75% max
species
setosa 50.0 1.464 0.173511 1.0 1.4 1.50 1.575 1.9
versicolor 50.0 4.260 0.469911 3.0 4.0 4.35 4.600 5.1
virginica 50.0 5.552 0.551895 4.5 5.1 5.55 5.875 6.9
petal_width ... sepal_length sepal_width \
count mean ... 75% max count mean
species ...
setosa 50.0 0.244 ... 5.2 5.8 50.0 3.418
versicolor 50.0 1.326 ... 6.3 7.0 50.0 2.770
virginica 50.0 2.026 ... 6.9 7.9 50.0 2.974
std min 25% 50% 75% max
species
setosa 0.381024 2.3 3.125 3.4 3.675 4.4
versicolor 0.313798 2.0 2.525 2.8 3.000 3.4
virginica 0.322497 2.2 2.800 3.0 3.175 3.8
[3 rows x 32 columns]
複数の集約関数の場合は, 関数の list を agg に渡す。
In [36]: iris.groupby('species').agg([np.mean, np.var])
Out[36]:
sepal_length sepal_width petal_length \
mean var mean var mean
species
setosa 5.006 0.124249 3.418 0.145180 1.464
versicolor 5.936 0.266433 2.770 0.098469 4.260
virginica 6.588 0.404343 2.974 0.104004 5.552
petal_width
var mean var
species
setosa 0.030106 0.244 0.011494
versicolor 0.220816 1.326 0.039106
virginica 0.304588 2.026 0.075433
In [37]: iris.groupby('species').agg(lambda x: x.std())
Out[37]:
sepal_length sepal_width petal_length petal_width
species
setosa 0.352490 0.381024 0.173511 0.107210
versicolor 0.516171 0.313798 0.469911 0.197753
virginica 0.635880 0.322497 0.551895 0.274650
おわりに
中編では pandas.DataFrame の連結・結合・グループ化を中心に紹介しました。後編では時系列データの処理について紹介します。
[1] Python pandas 図でみる データ連結 / 結合処理
[2] Merge, join, and concatenate