我有一個 (500000,30) numpy 陣列,我們可以將其視為長度為 500000 的大小為 30 的向量串列。我想在向量中選擇任意 4 個元素,計算其乘積,并存盤所有 4 元素乘積。最后我需要計算 500000 個結果的平均值。
我試過它,np.einsum但它運行得非常慢。我怎樣才能提高效率?
# array.shape = (500000,30)
expect = np.sum(np.einsum('ni,nj,nk,nr->ijkr',array,array,array,array),axis=0)/500000
uj5u.com熱心網友回復:
向量中 4 個條目的所有可能乘積v之和等于 的條目之和的 4 次方v。請注意,這假設相同的向量條目可以在一個產品中出現多次,并且總和將包括僅因其條目順序不同的產品(例如v[1] * v[2] * v[3] * v[4],v[4] * v[3] * v[2] * v[1]將被視為不同的產品)。由于您的代碼執行相同的計算,我假設這就是您想要的。在任何情況下,價值
np.sum(np.einsum('ni,nj,nk,nr->ijkr', array, array, array, array))
是一樣的
(array.sum(axis=1)**4).sum()
但后者的計算速度會快得多。
在您的代碼中,您沿 30x30x30x30 陣列的 0 軸求和np.einsum,但我不知道為什么。
uj5u.com熱心網友回復:
您可以通過分解最后一個維度中的點積來更有效地計算解決方案。此外,你可以告訴numpy的優化的einsum(以較高的延遲在這里是不是有問題的費用)。這是結果代碼:
expect = np.einsum('n,nj,nk,nr->jkr',np.sum(array, axis=1),array,array,array,optimize=True)/500000
這在我的機器上快了63 倍。如果您想進一步優化它,那么您可以使用多個執行緒并行執行計算。事實上,默認的 Numpy 實作是順序的。您可以使用Numba來做到這一點。我希望在我的 6 核機器上的計算速度大約快 360 倍(因為計算是計算系結的)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/339473.html
