Pythonでforループをベクトル化するとはどういう意味ですか?ネストされたforループを記述する別の方法はありますか?
私はPythonが初めてであり、私の研究では常にNumPyライブラリに出会います。
Python for
ループは、Cの対応するものよりも本質的に低速です。
numpy
がnumpy
配列でベクトル化されたアクションを提供するのはこのためです。 Pythonで通常行うfor
ループをCレベルまでプッシュします。これははるかに高速です。 numpy
は、そうでなければ要素ごとに行う必要のあるもの( "Pythonレベルfor
ループ)のベクトル化された(" Cレベルfor
ループ ")代替を提供します。
import numpy as np
from timeit import Timer
li = list(range(500000))
nump_arr = np.array(li)
def python_for():
return [num + 1 for num in li]
def numpy_add():
return nump_arr + 1
print(min(Timer(python_for).repeat(10, 10)))
print(min(Timer(numpy_add).repeat(10, 10)))
# 0.725692612368003
# 0.010465986942008954
numpy
ベクトル化された加算は、x70倍高速でした。
ウェスマッキーニーの 定義 を次に示します。
配列は、forループを作成せずにデータのバッチ操作を表現できるため重要です。これは通常、ベクトル化と呼ばれます。等しいサイズの配列間の算術演算は、要素ごとに演算を適用します。
ベクトル化バージョン:
>>> import numpy as np
>>> arr = np.array([[1., 2., 3.], [4., 5., 6.]])
>>> arr * arr
array([[ 1., 4., 9.],
[ 16., 25., 36.]])
ネイティブPython(入れ子になった)リストのループで同じこと:
>>> arr = arr.tolist()
>>> res = [[0., 0., 0.], [0., 0., 0.]]
>>> for idx1, row in enumerate(arr):
for idx2, val2 in enumerate(row):
res[idx1][idx2] = val2 * val2
>>> res
[[1.0, 4.0, 9.0], [16.0, 25.0, 36.0]]
これら2つの操作はどのように比較されますか? NumPyバージョンには436 nsかかります。 Pythonバージョンは3.52 µs(3520 ns)かかります。この「小さな」時間の大きな差はマイクロパフォーマンスと呼ばれ、より大きなデータを操作したり、数千または数百万の操作を繰り返す場合に重要になります回の。