こんにちは!インストラクターのフクロウです!
DataFrameにおいて、NumPyなどのユニバーサル関数を行ごと・列ごとに使いたいことがあります。
そんな時に便利なのがDataFrameのapplyメソッドです!
applyメソッドを使うことで、簡単にDataFrameに対する操作ができちゃいます。
この記事で「applyの使い方」や「どんな時に使うと嬉しいのか」がわかるので、ぜひ読んでみてください。
開発環境
この記事を書くために使った開発環境は以下のとおりです。
ライブラリのバージョンなど
- OS=”Ubuntu 18.04.1 LTS”
- Python 3.7.0
- Pandas 0.23.4
OSが異なっても基本的には同じ操作で記事中のプログラムは再現できるので、試してみてください!
applyのAPI
DataFrame.apply(func, # 適用したい関数 axis=0, # 0で行、1で列に対して適用 broadcast=None, raw=False, reduce=None, result_type=None, args=(), **kwds)
applyの引数は上の通りです。
引数が多くて混乱しそうですが、大切なのは最初の二つです。
- 第一引数func
- 適用したい関数
- 第二引数axis
- funcを行か列どちらに適用するか
これの使い方について、次のセクションで見ていきましょう。
また、この関数の詳しいAPI解説が書かれた公式ドキュメントは以下のリンクから確認できますよ。
applyの使い方
apply関数は行や列ごとにまとめて関数を適用してくれる関数なので、例えばNumPyの関数が使えます。
これを使って動作を確認してみましょう。
[前準備]サンプルデータ作成
まずはDataFrameを用意します。
In [1]: import numpy as np In [2]: import pandas as pd In [3]: data = np.arange(0,20).reshape((5,-1)) In [4]: df = pd.DataFrame(data) In [5]: df Out[5]: 0 1 2 3 0 0 1 2 3 1 4 5 6 7 2 8 9 10 11 3 12 13 14 15 4 16 17 18 19
簡単な使い方
この変数dfのDataFrameに対してapplyを使ってみます。
気にしたいのはaxisで列か行かを指定できる、というところですね。
In [6]: df.apply(np.sum) # axis=0 or axis="index"と同様 Out[6]: 0 40 1 45 2 50 3 55 dtype: int64 In [7]: df.apply(np.sum, axis=1) # axis="columns"と同様 Out[7]: 0 6 1 22 2 38 3 54 4 70 dtype: int64
出力のshapeを確認してください。
axis=0だと列数と同じサイズ、axis=1だと行数と同じサイズが出力されます。
applyで使える関数は、ここで例示したように「配列を受け取って一つの値を返す」タイプの関数だけでなく、「配列を受け取って配列を返す」関数も使えます。
ちなみに、この操作はNumPyだけでもできちゃいます。
In [8]: np.sum(df, axis=0) Out[8]: 0 40 1 45 2 50 3 55 dtype: int64 In [9]: np.sum(df, axis=1) Out[9]: 0 6 1 22 2 38 3 54 4 70 dtype: int64
appy同様の操作ができちゃいますね。
自作関数をapplyで使ってみる
NumPyの関数の例を見てみるとありがたみが薄いですが、自作関数にも使えるのがapplyの利点です。
これを試してみましょう。
n [10]: def mySum(X): ...: return sum(X) In [11]: df.apply(mySum) Out[11]: 0 40 1 45 2 50 3 55 dtype: int64 In [12]: df.apply(mySum, axis=1) Out[12]: 0 6 1 22 2 38 3 54 4 70 dtype: int64
applyで使える関数は、NumPyのようなユニバーサル関数になります。
ただし、実際にmySumのような関数に渡されるデータはpd.Series型オブジェクトのようなので、indexingの操作などは気を付けてください。
このように、numpy関数をそのまま使うだけだとapplyを使う価値は薄いかもしれませんが、自作関数では効果がありそうです。
リストのようなオブジェクトを受け取って答えを返す関数を用意すれば、あとは列ごと行ごとのどちらで適用するかをapplyのaxisで指定できて便利です。
まとめ
この記事ではPandasのapplyメソッドを紹介しました。
applyメソッドは
- 列ごと、行ごとに関数を適用できる
- ユニバーサル関数的な自作関数を用意するとDataFrameに対して便利に適用できる
点が優れています。
このほかにも、mapやapplymapのような同系列の関数もあります。
合わせて覚えて使ってみてくださいね。