背景
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)
でした。