我只想为特定索引有效地计算两个低秩矩阵A和B的点积。通常,A和B的形状为(100,10000),我只想获得A.T @ B的1%。
我已经尝试使用Numba库,但它似乎比计算密集点积np.dot(A.T,B)慢得多。
答案 0 :(得分:0)
如果要获得点乘积的结果数组的子集,只需在使用点之前取该子集即可。即,如果您想要输出的“左上” 10x10矩阵,只需执行
np.dot(A.T[:10,:], B[:, :10])
如果需要某些特定的索引,则可以使用更多的精美索引。例如,如果您想要索引3、5和29,则可以执行以下操作:
indices = np.array([3, 5, 29]).reshape(-1, 1)
inner_all = np.arange(A.shape[0]).reshape(-1, 1)
result = np.dot(A.T[indices, inner_all.T], B[inner_all, indices.T])
如果仅对于第一行,则需要第1、3和5列:
rows = np.array([1]).reshape(-1, 1)
columns = rows = np.array([1, 3, 5]).reshape(-1, 1)
inner_all = np.arange(A.shape[0]).reshape(-1, 1)
result = np.dot(A.T[rows, inner_all.T], B[inner_all, columns.T])
答案 1 :(得分:0)
您可以使用einsum
:
import numpy as np
def direct():
return (A.T@B)[iy, ix]
def einsum():
return np.einsum('ij,ij->j',A[:,iy],B[:,ix])
def make(M,N,p):
global A,B,iy,ix
A,B = (np.random.randint(0,10,(M,N)) for _ in "AB")
iy,ix = np.random.randint(0,N,(2,int(N*N*p)))
from time import time
make(100,10000,0.01)
T=[]
T.append(time())
d = direct()
T.append(time())
e = einsum()
T.append(time())
print("results equal: ",np.allclose(d,e))
print("direct {:.6f} einsum {:.6f}".format(*np.diff(T)))
样品运行:
results equal: True
direct 18.463711 einsum 1.947425