Python で解析 18

“Advent Calendar 2013 - Python で解析!” の十八日目。DataFrame - 13

今回は apply を取り上げる。DataFrame に任意の関数を実行するもので、 python の組み込み関数である map と思えばいいだろう。

1. データの準備

では、いつもの通りのデータの準備を。

In [1]: import pandas as pd

In [2]: df = pd.DataFrame({
   ...:   'height': [162, 178, 167, 171, 170],
   ...:   'weight1': [51, 80, 55, 68, 71],
   ...:   'weight2': [53, 75, 51, 68, 73]
   ...: })

In [3]: df
Out[3]:
   height  weight1  weight2
0     162       51       53
1     178       80       75
2     167       55       51
3     171       68       68
4     170       71       73

2. DataFrame に apply を適用

例えば偶数の判定は次のように書ける。

In [4]: df.apply(lambda x: x % 2 == 0)
Out[4]:
  height weight1 weight2
0   True   False   False
1   True    True   False
2  False   False   False
3  False    True    True
4   True   False   False

ただ、この程度だと式で書けてしまう…。(--;

In [5]: df % 2 == 0
Out[5]:
  height weight1 weight2
0   True   False   False
1   True    True   False
2  False   False   False
3  False    True    True
4   True   False   False

3. Series に apply を適用

いつものごとく、特定の列にだけ apply を適用することもできる。

In [6]: df.height.apply(lambda x: x % 2 == 0)
Out[6]:
0     True
1     True
2    False
3    False
4     True
Name: height, dtype: bool

いい例を思いつかないので、 FizzBuzz をやってみた。

In [7]: def fizzbuzz(x):
   ...:     def fizz(x):
   ...:         return 'Fizz' if x % 3 == 0 else ''
   ...:     def buzz(x):
   ...:         return 'Buzz' if x % 5 == 0 else ''
   ...:     val = fizz(x) + buzz(x)
   ...:     return val if len(val) > 0 else x
   ...:

In [8]: df.height.apply(fizzbuzz)
Out[8]:
0    Fizz
1     178
2     167
3    Fizz
4    Buzz
Name: height, dtype: object

せっかくなので、DataFrame にも FizzBuzz を適用してみるが、DataFrame の場合は引数に Series が渡されるので、その対応をする必要がある。

In [9]: def fizzbuzz(x):
   ...:     def fizz(x):
   ...:         return 'Fizz' if x % 3 == 0 else ''
   ...:     def buzz(x):
   ...:         return 'Buzz' if x % 5 == 0 else ''
   ...:     def temp(x):
   ...:         val = fizz(x) + buzz(x)
   ...:         return val if len(val) > 0 else x
   ...:     return [it for it in x.apply(temp)]
   ...:

In [10]: df.apply(fizzbuzz)
Out[10]:
  height weight1   weight2
0   Fizz    Fizz        53
1    178    Buzz  FizzBuzz
2    167    Buzz      Fizz
3   Fizz      68        68
4   Buzz      71        73

今回はこんなところで。