如何在没有toDense()的情况下将scipy.csr稀疏矩阵作为普通密集矩阵?

时间:2015-05-04 00:11:58

标签: python matrix scipy sparse-matrix

我在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,我只需将稀疏矩阵的数据数组与另一个矩阵相乘。这是对的吗?

1 个答案:

答案 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定义的常规数学运算。之后,如果你仍然要挤出更快的速度,你可以深入了解内部,并简化选定的操作。