今回はPandasでデータフレームの各要素に関数を適用する方法について紹介します。以前apply()について紹介しましたが、今回はapplymap()についてです。
各行ごと、列ごとに処理を行いたい場合はaplly()の方が適しています。apply()については以下をご覧ください。
applymap()とは
applymap()ではデータフレームの各要素に対して関数を適用することができます。各要素に対して共通の処理を実施したい場合に有効です。逆を言えば、applymap()では個々の要素に適用できるスカラー変換しかできません(例:全ての要素に2を掛ける等)。
applymapを使ってみる
簡単なデータフレームを作成し、それぞれの要素を2倍する処理をapplymapで実装してみます。
import pandas as pd
# データフレーム作成
df = pd.DataFrame({'A': [1, 2, 3], 'B': [10, 20, 30], 'C': [100, 200, 300]})
print(df)
>>
A B C
0 1 10 100
1 2 20 200
2 3 30 300
df_double = df.applymap(lambda x: x*2)
print(df_double)
>>
A B C
0 2 20 200
1 4 40 400
2 6 60 600
lambda関数を使って各要素を2倍する処理は上記のようになります。また、apply()同様Python関数を定義して呼び出すこともできます。
def double(x):
return x*2
df_double1 = df.applymap(double)
>>
A B C
0 2 20 200
1 4 40 400
2 6 60 600
異なる型の値を持つデータフレームの場合
要素に数値と文字列が混在する場合、足し算、掛け算等文字列にも適用可能な処理は実行できますが、割り算等はエラーになってしまいます。
あくまで、適用範囲の要素すべてにエラーなく実行できる処理である必要があります。
df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [10, 20, 30], 'C': ["a", "b", "c"]})
df_double2 = df.applymap(lambda x: x*2)
print(df_double2)
>>
A B C
0 2 20 aa
1 4 40 bb
2 6 60 cc
df_double2 = df1.applymap(lambda x: x/2)
print(df_double2)
>>
TypeError: unsupported operand type(s) for /: 'str' and 'int'
処理時間
applymap()はapply()よりも処理時間が速いです。どれくらい速いのか検証してみます。
3列40万件のデータを用意し、個々の要素を2乗する処理をapply()とapplymap()で実行してみます。
#約40万件にデータを複製する
df_big = df.copy(deep=True)
for i in range(17):
df_big = df_big.append(df_big)
print(len(df_big))
>>
393216
#2乗する関数
def square(x):
return x**2
df_square1 = df_big.apply(square, axis=1)
df_square2 = df_big.applymap(square)
apply()では1分30秒程度要したのに対し、applymap()ではなんと1秒を切っています。applymap()を使えるシチュエーションでは、applymap()を使うべきだというのは言うまでもありません。
apply() | applymap() |
---|---|
0:01:29.701849 | 0:00:00.869591 |
Pythonでデータサイエンスするなら
Pythonでデータサイエンスをするなら、以下の書籍がおすすめです。Pandas、matplotlib、Numpy、scikit-learnといったデータサイエンスに必要なライブラリを、体系立てて一通り学ぶことができます。
ややお値段高めですが、これ1冊で十分という内容・ボリュームなので、損はしないと思います^^
初学者の方にはこちらもオススメです^^
まとめ
applymap()を使ってPandasデータフレームの全ての要素に関数を適用する方法を紹介しました。全ての要素に対するスカラー変換しかできないという制限はありますが、かなり高速に処理することができるのがポイントです。applymapを使える場面では迷うことなく使うことをオススメします。
なお、apply()もapplymap()より複雑な処理を実現できるうえ、for文での処理よりもはるかに速いので、場面に応じて最適な実装をしてくださいね。
ではでは👋