背景
Python高速化のテクニック、ベクトル志向演算でどれだけ高速ができるか検証してみました。
高速化の題材は、for文ループを用いて、どれだけ差がでるかを検証してみました。
Python高速化については、以下を参照してください。
やってみた
テーマ設定
10万行のデータに対して、①2倍して②10引いて③半分にします
手法1
各行ごとに計算を実行します。
STEP = 100000 def method1(): df = pd.DataFrame() df['A'] = np.arange(STEP) for i in range(len(df)): df.loc[i, 'A'] *= 2 df.loc[i, 'A'] -= 10 df.loc[i, 'A'] /= 2
手法2
データフレームに対して、ベクトル志向で計算します。
STEP = 100000 def method2(): df = pd.DataFrame() df['A'] = np.arange(STEP) df['A'] *= 2 df['A'] -= 10 df['A'] /= 2
実行結果比較
計算結果を比較してみます
import time import numpy as np import pandas as pd STEP = 100000 def method1(): df = pd.DataFrame() df['A'] = np.arange(STEP) for i in range(len(df)): df.loc[i, 'A'] *= 2 df.loc[i, 'A'] -= 10 df.loc[i, 'A'] /= 2 def method2(): df = pd.DataFrame() df['A'] = np.arange(STEP) df['A'] *= 2 df['A'] -= 10 df['A'] /= 2 if __name__ == '__main__': start = time.time() method1() result_time1 = time.time() - start print(f'finish time of method1() is {result_time1} (sec)') start = time.time() method2() result_time2 = time.time() - start print(f'finish time of method2() is {result_time2} (sec)') print(f'処理時間は、約{int(result_time1 / result_time2)}倍異なります')
この結果、、、
finish time of method1() is 9.090620040893555 (sec) finish time of method2() is 0.003556966781616211 (sec) 処理時間は、約2555倍異なります
と、1000倍以上高速化させることができることがわかりました。
改めて、ベクトル志向で計算させることの重要性がわかる内容です。
おまけ
で紹介したiterrows()
やitertuples()
でも実行速度の比較をしてみました。
import time import numpy as np import pandas as pd STEP = 100000 def method1(): df = pd.DataFrame() df['A'] = np.arange(STEP) for i in range(len(df)): df.loc[i, 'A'] *= 2 df.loc[i, 'A'] -= 10 df.loc[i, 'A'] /= 2 def method2(): df = pd.DataFrame() df['A'] = np.arange(STEP) df['A'] *= 2 df['A'] -= 10 df['A'] /= 2 def method3(): df = pd.DataFrame() df['A'] = np.arange(STEP) for _, item in df.iterrows(): item['A'] = (item['A'] * 2 - 10) / 2 def method4(): df = pd.DataFrame() df['A'] = np.arange(STEP) for item in df.itertuples(): df.A = (df.A * 2 - 10) / 2 if __name__ == '__main__': start = time.time() method1() result_time1 = time.time() - start print(f'finish time of method1() is {result_time1} (sec)') start = time.time() method2() result_time2 = time.time() - start print(f'finish time of method2() is {result_time2} (sec)') start = time.time() method3() result_time3 = time.time() - start print(f'finish time of method3() is {result_time3} (sec)') start = time.time() method4() result_time4 = time.time() - start print(f'finish time of method4() is {result_time4} (sec)')
結果は、、、、、
finish time of method1() is 9.206869125366211 (sec) finish time of method2() is 0.003290891647338867 (sec) finish time of method3() is 1.6420342922210693 (sec) finish time of method4() is 16.61213994026184 (sec)
でした。