本事!
嗯,我攻入covariance func definition
,並把在規定輸入狀態:ddof=0, rowvar=False
和事實證明,一切都降低了,只是三線 -
nC = m.shape[1] # m is the 2D input array
X = m - m.mean(0)
out = np.dot(X.T, X)/nC
把它擴大到我們的3D陣列的情況下,我寫的向下多圈版本與這三條線被重複用於2D陣列的部分從3D輸入陣列,像這樣 -
for i,d in enumerate(m):
# Using np.cov :
org_cov = np.cov(d, ddof=0, rowvar=False)
# Using earlier 2D array hacked version :
nC = m[i].shape[0]
X = m[i] - m[i].mean(0,keepdims=True)
hacked_cov = np.dot(X.T, X)/nC
升壓它向上
我們需要加快最後三行。在所有迭代X
計算可以用做broadcasting
-
diffs = data - data.mean(1,keepdims=True)
接下來,點積運算的各個版本可以與transpose
和np.dot
來完成,但transpose
可能是這樣的多昂貴的事情維數組。存在更好的選擇在np.einsum
,像這樣 -
cov3D = np.einsum('ijk,ijl->ikl',diffs,diffs)/data.shape[1]
使用它!
綜上所述:
for d in data:
# compute covariance for each triangle
cov = np.cov(d, ddof=0, rowvar=False)
可以預先計算,如下所示:
diffs = data - data.mean(1,keepdims=True)
cov3D = np.einsum('ijk,ijl->ikl',diffs,diffs)/data.shape[1]
這些預計算值可以跨迭代被用來計算像這樣的本徵矢量 -
for i,d in enumerate(data):
# Directly use pre-computed covariances for each triangle
vals, vecs = np.linalg.eig(cov3D[i])
測試它!
這裏有一些運行測試,以評估的前期計算的協方差結果的影響 -
In [148]: def original_app(data):
...: cov = np.empty(data.shape)
...: for i,d in enumerate(data):
...: # compute covariance for each triangle
...: cov[i] = np.cov(d, ddof=0, rowvar=False)
...: return cov
...:
...: def vectorized_app(data):
...: diffs = data - data.mean(1,keepdims=True)
...: return np.einsum('ijk,ijl->ikl',diffs,diffs)/data.shape[1]
...:
In [149]: data = np.random.randint(0,10,(1000,3,3))
In [150]: np.allclose(original_app(data),vectorized_app(data))
Out[150]: True
In [151]: %timeit original_app(data)
10 loops, best of 3: 64.4 ms per loop
In [152]: %timeit vectorized_app(data)
1000 loops, best of 3: 1.14 ms per loop
In [153]: data = np.random.randint(0,10,(5000,3,3))
In [154]: np.allclose(original_app(data),vectorized_app(data))
Out[154]: True
In [155]: %timeit original_app(data)
1 loops, best of 3: 324 ms per loop
In [156]: %timeit vectorized_app(data)
100 loops, best of 3: 5.67 ms per loop
謝謝!順便說一句,在你的例子中,你不需要''爲我,在枚舉(數據):'''你可以傳遞整個'cov3D'數組,例如'vals,vecs = np.linalg.eig(cov3D)'性能提升20倍 – Fnord