web-dev-qa-db-ja.com

ベクトル化とは何ですか?

Pythonでforループをベクトル化するとはどういう意味ですか?ネストされたforループを記述する別の方法はありますか?

私はPythonが初めてであり、私の研究では常にNumPyライブラリに出会います。

13
JP Nollav

Python forループは、Cの対応するものよりも本質的に低速です。

numpynumpy配列でベクトル化されたアクションを提供するのはこのためです。 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倍高速でした。

20
DeepSpace

ウェスマッキーニーの 定義 を次に示します。

配列は、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)かかります。この「小さな」時間の大きな差はマイクロパフォーマンスと呼ばれ、より大きなデータを操作したり、数千または数百万の操作を繰り返す場合に重要になります回の。

10
Brad Solomon