我有一個numpy的操作,我稱之爲集中,我需要優化:聚合numpy的功能
np.sum(a**2, axis=1)**.5 # where a is a 2 dimensional ndarray
這一操作是由三個功能,需要通過「A」三次迭代。將一個功能下的所有操作聚合在一起並沿軸1使用該功能會更有效率。不幸的是,numpy的apply_along_axis功能不是一種選擇,因爲性能在x1000左右更差。
有沒有聚合幾個numpy操作的方法,所以它只需要在數組上循環一次?
我有一個numpy的操作,我稱之爲集中,我需要優化:聚合numpy的功能
np.sum(a**2, axis=1)**.5 # where a is a 2 dimensional ndarray
這一操作是由三個功能,需要通過「A」三次迭代。將一個功能下的所有操作聚合在一起並沿軸1使用該功能會更有效率。不幸的是,numpy的apply_along_axis功能不是一種選擇,因爲性能在x1000左右更差。
有沒有聚合幾個numpy操作的方法,所以它只需要在數組上循環一次?
當浮點陣列時,您可以使用np.einsum
-
np.sqrt(np.einsum('ij,ij->i',a,a))
運行測試 -
In [34]: a = np.random.rand(1000,1000)
In [35]: np.allclose(np.sum(a**2, axis=1)**.5,np.sqrt(np.einsum('ij,ij->i',a,a)))
Out[35]: True
In [36]: %timeit np.sum(a**2, axis=1)**.5
100 loops, best of 3: 7.57 ms per loop
In [37]: %timeit np.sqrt(np.einsum('ij,ij->i',a,a))
1000 loops, best of 3: 1.52 ms per loop
看看numexpr
,它可以讓你更快的計算數值表達式比純numpy
:
In [19]: a = np.arange(1e6).reshape(1000,1000)
In [20]: import numexpr as ne
In [21]: %timeit np.sum(a**2,axis=1)**0.5
100 loops, best of 3: 6.08 ms per loop
In [22]: %timeit ne.evaluate("sum(a**2,axis=1)")**0.5
100 loops, best of 3: 4.27 ms per loop
的**0.5
不是表達式的一部分,因爲sum
是還原操作,需要計算的最後在表達式中。您還可以對sqrt
/**0.5
運行另一項評估。
'numexpr'爲'sqrt'過,所以也許可以幫助更換' ** 0.5'?儘管這可能意味着嵌套兩個「評估」電話。 – Divakar
'sqrt'只花了'sum'的大約1%的時間,所以我認爲這是一點不必要的優化。 –
謝謝。這比我預期的還要好! – MonkeyButter
@MonkeyButter很高興幫助! 'np.einsum'是純粹的魔法! :) – Divakar