我在scipy中遇到稀疏矩阵的问题。我想将它们用作普通矩阵,但不能用于todense()函数。我是这个领域的新手,我不知道当我想要稀疏矩阵时,我怎么能得到相同的结果,但是没有稀疏矩阵...我认为稀疏矩阵只用于更快的计算,所以它应该是可能的在没有稀疏矩阵的情况下做到这一点:
sparse_matrix * 5 == sparase_matrix.todense()* 5 == no_sparse_matrix * 5
data = np.ones(5178)
indices = [34,12,545,23...,25,18,29] Shape:5178L
indptr = np.arange(5178 + 1)
sparse_matrix = sp.csr_matrix((data, indices, indptr), shape = (5178, 3800))
这是对的吗?
sparse_matrix * 5 == sparase_matrix.todense() * 5 == data * 5 ?
我的目标是获得与稀疏矩阵相乘而不使用稀疏矩阵时相同的结果?这可能吗?我怎么能这样做?
编辑:关于我的意图: 我的问题是我想将一个python代码转移到java中,而我的java libary for linear algeba不提供稀疏矩阵运算。
所以我必须在没有稀疏矩阵的java中做同样的事情。我不确定,如果我可以使用数据数组而不是稀疏矩阵。
在原始代码中,稀疏矩阵与另一个矩阵相乘。 要将它传递给java,我只需将稀疏矩阵的数据数组与另一个矩阵相乘。这是对的吗?
答案 0 :(得分:2)
你要求的并不完全清楚,但这是我的猜测。
让我们试试一个简单的数组:
从3个数组开始(我从另一个稀疏矩阵中获取这些数据,但这并不重要):
In [165]: data
Out[165]: array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], dtype=int32)
In [166]: indices
Out[166]: array([1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], dtype=int32)
In [167]: indptr
Out[167]: array([ 0, 3, 7, 11], dtype=int32)
In [168]: M=sparse.csr_matrix((data,indices,indptr),shape=(3,4))
这些数组已分配给新矩阵的3个属性
In [169]: M.data
Out[169]: array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], dtype=int32)
In [170]: M.indices
Out[170]: array([1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], dtype=int32)
In [171]: M.indptr
Out[171]: array([ 0, 3, 7, 11], dtype=int32)
现在尝试乘以.data
属性:
In [172]: M.data *= 3
低,看到我们已经乘以'整个'数组
In [173]: M.A
Out[173]:
array([[ 0, 3, 6, 9],
[12, 15, 18, 21],
[24, 27, 30, 33]], dtype=int32)
当然我们也可以直接乘以矩阵。也就是说,为csr稀疏矩阵定义乘以常数:
In [174]: M *= 2
In [175]: M.A
Out[175]:
array([[ 0, 6, 12, 18],
[24, 30, 36, 42],
[48, 54, 60, 66]], dtype=int32)
In [176]: M.data
Out[176]: array([ 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66], dtype=int32)
出于好奇,让我们看看源数组。它也发生了变化。所以M.data
指向同一个数组。改变一个,改变另一个。
In [177]: data
Out[177]: array([ 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66], dtype=int32)
因此,当以这种方式创建矩阵时,可以通过几种不同的方式将其乘以标量。
哪个最好?直接乘以.data
属性可能比乘以矩阵更快。但是你应该意识到直接操纵.data
和对整个矩阵使用定义的数学运算之间的区别。例如,M*N
执行矩阵乘法。在尝试直接更改其内部结构之前,您真的应该了解矩阵数据结构。
修改源数组data
的能力取决于以这种方式创建矩阵,并维护指针链接。如果您通过coo
矩阵(或coo
样式输入)定义,则不会保留data
链接。 M1 = M*2
不会将此链接传递给M1
。
让您的代码使用sparse
定义的常规数学运算。之后,如果你仍然要挤出更快的速度,你可以深入了解内部,并简化选定的操作。