在简单的向量矩阵乘法中,当使用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
(实际上是一个二维数组)不会改变结果。
答案 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
的子类。