1 回答

TA貢獻1784條經(jīng)驗 獲得超7個贊
我會做這樣的事情:
def updown(x):
result = np.zeros_like(x)
for i in range(len(x)):
mid = (len(x)+1)//2
a = x[:mid].mean(axis=0)
b = x[-mid:].mean(axis=0)
mask_a = a != 0
mask_b = (a == 0) & (b != 0)
result[i, mask_a] = (b[mask_a] - a[mask_a]) / abs(a[mask_a])
result[i, mask_b] = (b[mask_b] - a[mask_b]) / abs((a[mask_b] + b[mask_b])/2)
x = x[1:]
return result
在循環(huán)相當(dāng)不可避免的情況下,最好預(yù)先分配結(jié)果數(shù)組(如果事先知道維度)并填充循環(huán)中的值。這還具有允許預(yù)先填充默認值零的優(yōu)點。
無需在 列上應(yīng)用任何內(nèi)容,因為其他運算(和算術(shù))可以很容易地應(yīng)用于所選軸。xmean
條件邏輯是通過屏蔽實現(xiàn)的。
您還可以使用 和 關(guān)鍵字參數(shù):outwherenp.divide
def updown(x):
result = np.zeros_like(x)
for i in range(len(x)):
mid = (len(x)+1)//2
a = x[:mid].mean(axis=0)
b = x[-mid:].mean(axis=0)
np.divide(b - a, abs(a), out=result[i], where=(a != 0))
np.divide(b - a, abs((a + b)/2), out=result[i], where=(a == 0) & (b != 0))
x = x[1:]
return result
讓我們看看一些性能比較(我已經(jīng)將整個原始代碼包裝在一個名為updown_orig)
對于維度,我們只看到 2 倍的改進:(20, 5)
In []: %timeit updown_orig(np.random.rand(20, 5))
1 ms ± 13.9 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In []: %timeit updown(np.random.rand(20, 5))
508 μs ± 10.2 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
讓我們將兩個維度縮放 10(將 大小增加 100 倍):x
In []: %timeit updown_orig(np.random.rand(200, 50))
96.4 ms ± 1.91 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In []: %timeit updown(np.random.rand(200, 50))
5.84 ms ± 64 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
現(xiàn)在,差異約為16.5倍。
添加回答
舉報