次の Numpy 配列があるとします。
array([[3, 5, 0], [7, 0, 2]])
値が 0 ではない 2 を追加したいのですが、これを行う最も速い方法は何ですか? 非常に大きな多次元配列を操作する必要がありますか?
それは私には思われる:
a[a!=0] += 2
動作するはずです。
(非ゼロ性をテストする限られたケースの場合)、次のようにして高速化できる場合がtimeit
あります(確認する必要があります):
mask = a.astype(bool)
a[mask] += 2
もちろん、同じマスクを別の場所で再利用できる場合は、マスクの計算を節約できます(これはかなり制限的な制約です)。
mask = a != 0
a[mask] += 2
#some more code ...
a[mask] *= 3
#more code ...
もちろん、これが十分なボトルネックである場合は、これを行うための小さな C/Fortran 拡張機能をいつでも作成できます (Cython
またはf2py
それぞれを使用)。これにより、マスク作成のオーバーヘッドが回避されます。
配列のサイズによって異なりますが、これにはnumexprを使用することを検討できます。
# from your exemmple
>>> a = array([[3, 5, 0], [7, 0, 2]])
>>> %timeit a[a!=0] += 2
100000 loops, best of 3: 18.6 us per loop
>>> timeit numexpr.evaluate("a + 2 * (a != 0)")
10000 loops, best of 3: 42.6 us per loop
しかし、より大きな配列では:
# make a big array with 10% of zeros :
a = np.random.rand(10000)
a[a<0.1] = 0
# same test:
>>> timeit a[a!=0] += 2
1000 loops, best of 3: 364 us per loop
>>> timeit numexpr.evaluate("a + 2 * (a != 0)")
10000 loops, best of 3: 119 us per loop
そして、これはシングルコアです。Numepxr は、可能であれば利用可能なすべてのコアを利用します。