比方說,我有以下numpy的數組:選擇性numpy的數組操作(取決於值)
array([[3, 5, 0], [7, 0, 2]])
我現在要加2,其中值不爲0,什麼是做到這一點的最快方法?我必須操縱相當大的多維數組?
比方說,我有以下numpy的數組:選擇性numpy的數組操作(取決於值)
array([[3, 5, 0], [7, 0, 2]])
我現在要加2,其中值不爲0,什麼是做到這一點的最快方法?我必須操縱相當大的多維數組?
在我看來是:
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儘可能使用所有可用內核。
重用掩碼是一個好主意,但它可能不會反映當前狀態(想象數組中有一個'-2',並且您想要添加2次兩次)。 – eumiro
@eumiro - 是的。 *如果你可以重複使用相同的掩碼*是一個相當嚴格的約束。 – mgilson
@mgilson - 這很有趣,因爲numpy的行爲與以前不同。 「a [a!= 0] + = 2」與「a = a [a!= 0] + 2」的結果不一樣。 – Zardoz