矢量矩阵稀疏和密集矩阵之间的产品差异

时间:2016-10-29 05:24:44

标签: python numpy scipy sparse-matrix

在简单的向量矩阵乘法中,当使用scipy.sparse矩阵而不是密集矩阵时,我得到不同的结果/输出格式。作为一个例子,我使用以下密集矩阵和向量:

import numpy as np
from scipy import sparse
mat = np.array([[1, 1, 0, 0, 0], [0, 2, 2, 0, 0], [0, 0, 3, 3, 0], [0, 0, 0, 4, 4]])
vec = np.arange(1, 5)

对于矢量矩阵乘积,我得到以下预期输出:

vec.dot(mat)   # array([ 1,  5, 13, 25, 16])
mat.T.dot(vec) # array([ 1,  5, 13, 25, 16])
mat.T.dot(vec.T) # array([ 1,  5, 13, 25, 16])

我接受如果载体是否转置它不起作用。但是当我用稀疏矩阵mat替换矩阵mat_sparse时,我得到一个稀疏4x5矩阵的数组,其中包含稀疏矩阵乘以每个向量分量,即[1x mat_sparse, 2x mat_sparse, ...]

mat_sparse = sparse.lil_matrix(mat)
vec.dot(mat_sparse)  # array([ <4x5 sparse matrix of type '<type 'numpy.int64'>' with 8 stored elements in LInked List format>, ...], dtype=object)

使用转置矩阵技巧我获得了预期的结果:

mat_sparse.T.dot(vec4.T)  # array([ 1,  5, 13, 25, 16])

有人可以解释为什么这种行为是预期/想要的吗?用mat实例替换矩阵np.matrix(mat(实际上是一个二维数组)不会改变结果。

2 个答案:

答案 0 :(得分:0)

使用sparse矩阵的操作结果通常也是sparse矩阵。

如果你想转换回密集矩阵,你需要在结果上使用.toarray()方法来询问。

答案 1 :(得分:0)

作为一般规则,不要依赖于使用稀疏矩阵的numpy函数和方法。最好使用稀疏方法和函数。常规的numpy代码对稀疏矩阵一无所知。

使用矩阵(稀疏或np.matrix),*是矩阵乘法。

In [2150]: vec*smat    # smat=csr_matrix(mat)
Out[2150]: array([ 1,  5, 13, 25, 16], dtype=int32)

在此上下文中,*的稀疏矩阵定义优先。

In [2151]: vec.dot(smat)
Out[2151]:...
array([ <4x5 sparse matrix of type '<class 'numpy.int32'>'
    with 8 stored elements in Compressed Sparse Row format>,
    ...
    with 8 stored elements in Compressed Sparse Row format>], dtype=object)

在这个表达式中,vec.dot对稀疏矩阵一无所知。关闭它似乎与dot的每一行分别执行smat,但我必须进一步挖掘。

以下情况有效,因为它使用dot的稀疏定义,与其*相同:

In [2163]: smat.T.dot(vec)
Out[2163]: array([ 1,  5, 13, 25, 16], dtype=int32)

np.dot对稀疏矩阵的理解有限。例如,如果两个参数都是稀疏的,则它可以工作。 np.dot(smat, smat.T)有效(与np.dot(mat, mat.T)相同)

In [2177]: np.dot(smat.T,sparse.csr_matrix(vec).T).A
Out[2177]: 
array([[ 1],
       [ 5],
       [13],
       [25],
       [16]], dtype=int32)

阅读如何创建稀疏矩阵并存储其数据可能会有所帮助。它们不是np.ndarray的子类。