通过稀疏向量有效地乘以密集矩阵

时间:2015-04-25 22:31:13

标签: python python-2.7 scipy sparse-matrix

我正在寻找一种将密集矩阵乘以稀疏向量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。

都很快的单一实现

0 个答案:

没有答案