我有一個簡單的代數問題,我想用numpy解決它(當然我可以用numba輕松解決它,但這不是重點)。
讓我們考慮大小為 (mxn)的第一個隨機矩陣A,其值為 na 大,以及第二個隨機矩陣B的大小為 (nxn)。
A = np.random.random((1E6, 1E2))
B = np.random.random((1E2, 1E2))
我們要計算以下運算式:
np.diag(np.dot(np.dot(A,B),B.T))
問題是整個矩陣被加載到記憶體中,然后才提取對角線。是否有可能以更有效的方式進行此操作?
uj5u.com熱心網友回復:
這就是我從你的開始表達中接近它的方式
np.diag(np.dot(np.dot(A,B),B.T))
您可以從分組術語開始:
np.diag(np.dot(A, np.dot(B,B.T)))
然后只使用 A 的第一個相關(正方形)部分:
np.diag(np.dot(A[:B.shape[0], :], np.dot(B,B.T)))
然后通過自己進行元素乘法來避免額外的乘法(會落在對角線上):
np.sum( np.multiply(A[:B.shape[0], :].T, np.dot(B,B.T)), 0)
uj5u.com熱心網友回復:
- 改變
(A*B)*B.T以A*(B*B.T) - 僅乘以 A (
A[:B.shape[0]]) 的這部分,這將導致矩陣的對角線部分
import numpy as np
import time
A = np.random.random((1000_000, 100))
B = np.random.random((100, 100))
start_time = time.time()
result = np.diag(np.dot(np.dot(A, B), B.T))
print('Baseline: ', time.time() - start_time)
start_time = time.time()
for i in range(100):
result2 = np.diag(np.dot(A[:B.shape[0]], np.dot(B, B.T)))
print('Optimized: ', (time.time() - start_time) / 100)
stop = 1
assert np.allclose(result, result2)
Baseline: 1.7957241535186768
Optimized: 0.00016015291213989258
uj5u.com熱心網友回復:
是的。
N = 1E6
A = np.random.random((N, 1E2))
B = np.random.random((1E2, 1E2))
result = 0;
for i in range(N):
result = np.dot(np.dot(A[i,:], B[i,:])[i, :], B.T[i, :])
# Replacing B.T[i, :] with B[:, i].T might be a little more efficient
解釋:
假設我們有:K = np.dot(np.dot(A,B),B.T)。
然后, K[0,0] = (A[0, :] * B[:,0])[0, :] * B.T[:])
- 設
X = (A[0, :] * B[:,0]),這是[0, 0]元素np.dot(A,B) - 然后
X[0, :] * B.T[:, 0]是[0, 0]元素np.dot(np.dot(A,B),B.T) - 那么
X[0, :] * B.T[:, 0]=(A[0, :] * B[:,0])[0, :] * B.T[:])
我們也可以將這個結果概括為: K[i,i] = (A[i, :] * B[:,i])[i, :] * B.T[:, i])
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/352627.html
