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

How do I get a scipy.csr sparse-matrix as a normal dense matrix without toDense()?

我在 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 线性代数库不提供稀疏矩阵运算。

所以我必须在没有稀疏矩阵的 java 中做同样的事情。我不确定是否可以只使用数据数组而不是稀疏矩阵。

在原始代码中,一个稀疏矩阵与另一个矩阵相乘。 要将其传输到 java,我只需将稀疏矩阵的数据数组与另一个矩阵相乘。这是正确的吗?

不完全清楚你的要求,但这是我的猜测。

让我们用一个简单的数组来做实验:

从 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

低,我们已经乘以 'whole' 数组

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 的能力取决于以这种方式创建矩阵并维护该指针 link。如果您通过 coo 矩阵(或 coo 样式输入)定义它,则不会维护 data link。 M1 = M*2 不会将此 link 传递给 M1

让您的代码使用 sparse 已定义的正常数学运算。以后如果还想榨取更多的速度,可以深入内部,精简选定的操作。