我正在寻找一种将密集矩阵乘以稀疏向量Av
的有效方法,其中A的大小为(M x N),v为(N x 1)。向量v是scipy.sparse.csc_matrix。
我目前使用两种方法:
在方法1中,我选择v中的非零值,比如vi,以及元素乘法vi和A的相应列,然后将这些列相加。因此,如果y = Av
,则y = A[:, 0]*v0 + ... + A[:, N]*vN
,仅适用于非零i。
def dense_dot_sparse(dense_matrix, sparse_column):
prod = np.zeros((dense_matrix.shape[0]))
r, c = sparse_column.nonzero()
indices = zip(r, c)
for ind in indices:
prod = prod + dense_matrix[:, ind[1]] * sparse_column[ind]
return prod
在方法2中,我通过简单地制作稀疏向量.todense()
并使用np.dot()
来执行乘法。
def dense_dot_sparse2(dense_matrix, sparse_column):
return np.dot(dense_matrix, sparse_column.todense())
A的典型大小为(512 x 2048),v的稀疏度在1到200个非零条目之间变化。我根据v的稀疏度选择采用哪种方法。如果v的稀疏度为〜200非零,则方法1需要~45ms,方法2需要~5ms。但是当v非常稀疏时,~1非零,则方法1需要~1ms,而方法2仍需要5ms。检查v(.nnz
)的稀疏性几乎增加了0.2ms。
我必须执行大约1500次这些乘法(在分割我的数据和多处理之后),所以时间加起来。
[编辑:添加一个简单的代表性示例
rows = 512
cols = 2048
sparsity = 0.001 # very sparse: 0.001 for ~ 1 non-zero, moderately sparse: 0.1 for ~ 200 non-zero
big_matrix = np.random.rand(rows, cols) # use as dense matrix
col = np.random.rand(cols, 1)
col = np.array([i[0] if i < sparsity else 0.0 for i in col])
sparse_col = csc_matrix(col) # use as sparse vector
print sparse_col.nnz
结束编辑]
我正在寻找一种对于非常稀疏和中度稀疏的v。
都很快的单一实现