2012-09-27 74 views

回答

5

在我看來是:

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擴展爲您做這件事(分別使用Cythonf2py)。這將避免掩模創建的開銷。

+0

重用掩碼是一個好主意,但它可能不會反映當前狀態(想象數組中有一個'-2',並且您想要添加2次兩次)。 – eumiro

+0

@eumiro - 是的。 *如果你可以重複使用相同的掩碼*是一個相當嚴格的約束。 – mgilson

+0

@mgilson - 這很有趣,因爲numpy的行爲與以前不同。 「a [a!= 0] + = 2」與「a = a [a!= 0] + 2」的結果不一樣。 – Zardoz

1

這取決於你的數組的大小,但你可以考慮使用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儘可能使用所有可用內核。