Pandasデータフレームを使用していて、既存の列の関数として新しい列を作成したいと思います。私はとの速度差の良い議論を見ていないdf.apply()
とnp.vectorize()
私は、私はここに求めるだろうと思ったので、。
パンダのapply()
機能は遅いです。私が測定したもの(いくつかの実験で以下に示す)から、少なくとも私の2016 MacBook Proでは、np.vectorize()
使用はDataFrame関数を使用するよりも25倍高速(またはそれ以上)ですapply()
。これは期待される結果ですか、そしてその理由は何ですか?
たとえば、次のN
行のあるデータフレームがあるとします。
N = 10
A_list = np.random.randint(1, 100, N)
B_list = np.random.randint(1, 100, N)
df = pd.DataFrame({'A': A_list, 'B': B_list})
df.head()
# A B
# 0 78 50
# 1 23 91
# 2 55 62
# 3 82 64
# 4 99 80
さらに、2つの列A
との関数として新しい列を作成するとしB
ます。以下の例では、単純な関数を使用しますdivide()
。関数を適用するには、df.apply()
またはのいずれかを使用できますnp.vectorize()
:
def divide(a, b):
if b == 0:
return 0.0
return float(a)/b
df['result'] = df.apply(lambda row: divide(row['A'], row['B']), axis=1)
df['result2'] = np.vectorize(divide)(df['A'], df['B'])
df.head()
# A B result result2
# 0 78 50 1.560000 1.560000
# 1 23 91 0.252747 0.252747
# 2 55 62 0.887097 0.887097
# 3 82 64 1.281250 1.281250
# 4 99 80 1.237500 1.237500
N
100万以上のような実世界のサイズに拡大するnp.vectorize()
と、25倍またはそれ以上の速度であることがわかりますdf.apply()
。
以下は、いくつかの完全なベンチマークコードです。
import pandas as pd
import numpy as np
import time
def divide(a, b):
if b == 0:
return 0.0
return float(a)/b
for N in [1000, 10000, 100000, 1000000, 10000000]:
print ''
A_list = np.random.randint(1, 100, N)
B_list = np.random.randint(1, 100, N)
df = pd.DataFrame({'A': A_list, 'B': B_list})
start_epoch_sec = int(time.time())
df['result'] = df.apply(lambda row: divide(row['A'], row['B']), axis=1)
end_epoch_sec = int(time.time())
result_apply = end_epoch_sec - start_epoch_sec
start_epoch_sec = int(time.time())
df['result2'] = np.vectorize(divide)(df['A'], df['B'])
end_epoch_sec = int(time.time())
result_vectorize = end_epoch_sec - start_epoch_sec
print 'N=%d, df.apply: %d sec, np.vectorize: %d sec' % \
(N, result_apply, result_vectorize)
# Make sure results from df.apply and np.vectorize match.
assert(df['result'].equals(df['result2']))
結果を以下に示します。
N=1000, df.apply: 0 sec, np.vectorize: 0 sec
N=10000, df.apply: 1 sec, np.vectorize: 0 sec
N=100000, df.apply: 2 sec, np.vectorize: 0 sec
N=1000000, df.apply: 24 sec, np.vectorize: 1 sec
N=10000000, df.apply: 262 sec, np.vectorize: 4 sec
場合は、np.vectorize()
常により速くよりも一般的でありdf.apply()
、なぜされnp.vectorize()
、より言及されていませんか?次のdf.apply()
ような、に関連するStackOverflowの投稿のみが表示されます。
np.vectorize
が、基本的にはpythonfor
ループ(これは便利なメソッドです)でapply
あり、ラムダはpython時間でもあります