原始問題高效縱列相關係數計算
我大小爲n的P列相關,以大小爲n×米的矩陣的O每一列。我製作了下面的代碼:
import numpy as np
def ColumnWiseCorrcoef(O, P):
n = P.size
DO = O - (np.sum(O, 0)/np.double(n))
DP = P - (np.sum(P)/np.double(n))
return np.dot(DP, DO)/np.sqrt(np.sum(DO ** 2, 0) * np.sum(DP ** 2))
它比天真的方法更有效:
def ColumnWiseCorrcoefNaive(O, P):
return np.corrcoef(P,O.T)[0,1:O[0].size+1]
以下是我與numpy的-1.7.1-MKL得到了Intel Core時序:
O = np.reshape(np.random.rand(100000), (1000,100))
P = np.random.rand(1000)
%timeit -n 1000 A = ColumnWiseCorrcoef(O, P)
1000 loops, best of 3: 787 us per loop
%timeit -n 1000 B = ColumnWiseCorrcoefNaive(O, P)
1000 loops, best of 3: 2.96 ms per loop
現在的問題:你可以建議一個更快的版本的代碼這個問題?擠出額外的20%會很好。
UPDATE 2017年5月
後相當長的一段時間我回到這個問題,重新運行,延長了任務和測試。
使用einsum,我已經將代碼擴展到P不是行而是矩陣的情況。因此,任務是將O的所有列與P的所有列相關聯。對於如何用通常用於科學計算的不同語言解決同一問題感到好奇,我在其他人的幫助下實施了它(在其他人的幫助下) MATLAB,Julia和R. MATLAB和Julia是最快的,他們有專門的例程來計算列向相關性。 R還有一個專門的例程,但是最慢。
在numpy的當前版本(1.12.1來自Anaconda)中,einsum仍勝過我使用的專用函數。
所有的腳本和計時都在https://github.com/ikizhvatov/efficient-columnwise-correlation。
可以改變'O'和'P'嗎?而且這些方法在很大程度上依賴於鏈接到numpy的BLAS庫,如果你還沒有,我會建議使用某種優化的BLAS。 – Daniel
@Ophion,'P'可以改變,'O'不能。我使用從http://www.lfd.uci.edu/~gohlke/pythonlibs/鏈接到英特爾MKL的numpy。 – ilya
目前無法測試,但如果您嘗試使用np.einsum('ij,ij-> j',DO,DO)'而不是'np.sum(DO ** 2, 0)'和'np.dot(DP,DP)'而不是'np.sum(DP ** 2)'。 – Jaime