【发布时间】:2014-09-20 05:22:51
【问题描述】:
假设我们想为给定的稀疏矩阵 A,B 计算 C=A*B,但对 C 的一个非常小的条目子集感兴趣,由索引对列表表示:
行=[i1, i2, i3 ... ]
cols=[j1, j2, j3 ... ]
A 和 B 都很大(比如 50Kx50K),但非常稀疏(
我们如何计算这个乘法子集?
这是一个运行速度非常慢的简单实现:
def naive(A, B, rows, cols):
N = len(rows)
vals = []
for n in xrange(N):
v = A.getrow(rows[n]) * B.getcol(cols[n])
vals.append(v[0, 0])
R = sps.coo_matrix((np.array(vals), (np.array(rows), np.array(cols))), shape=(A.shape[0], B.shape[1]), dtype=np.float64)
return R
即使对于小矩阵,这也很糟糕:
import scipy.sparse as sps
import numpy as np
D = 1000
A = np.random.randn(D, D)
A[np.abs(A) > 0.1] = 0
A = sps.csr_matrix(A)
B = np.random.randn(D, D)
B[np.abs(B) > 0.1] = 0
B = sps.csr_matrix(B)
X = np.random.randn(D, D)
X[np.abs(X) > 0.1] = 0
X[X != 0] = 1
X = sps.csr_matrix(X)
rows, cols = X.nonzero()
naive(A, B, rows, cols)
在我的机器上,naive() 在 1 分钟后完成,大部分精力都花在了构造行/列上(在 getrow() 和 getcol() 中)。
当然,将这个(非常小的)示例转换为密集矩阵,计算大约需要 100 毫秒:
A0 = np.array(A.todense())
B0 = np.array(B.todense())
X0 = np.array(X.todense())
A0.dot(B0) * X0
关于如何有效地计算这种矩阵乘法有什么想法吗?
- 注意:此问题与以下问题几乎相同:
Subset of a matrix multiplication, fast, and sparse
但是,A 和 B 是 full 矩阵,并且其中一个维度非常低(例如,10) 提议的解决方案似乎同时受益于两者。
【问题讨论】:
标签: python numpy matrix scipy cython