使用花式索引修改稀疏矩阵

Modifying sparce matrix using fancy indexing

我正在尝试使用花式索引来修改大型稀疏矩阵。假设您有以下代码:

import numpy as np
import scipy.sparse as sp

a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
b = sp.lil_matrix(a)
c = sp.lil_matrix((3,4))
c[[1,2], 0] = b[[1,2], 0]

然而,此代码给出以下错误:

ValueError: shape mismatch in assignment

我不明白为什么这不起作用。两个矩阵具有相同的形状,如果两个矩阵都是 numpy 数组,这通常有效。如果有任何帮助,我将不胜感激。

是的,这是稀疏 __setitem__ 的错误。我之前已经 运行 进入了它(但我只是解决了它)。现在我真的调查了它;首先,你可以很容易地解决这个问题:

import numpy as np
import scipy.sparse as sp

a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
b = sp.lil_matrix(a)
c = sp.lil_matrix((3,4))
c[[1,2], 0] = b[[1,2], 0]

这提高了您看到的 ValueError。这不会并按预期工作:

c[[1,2], 0] = b[[1,2], [0]]

>>> c.A
array([[0., 0., 0., 0.],
       [5., 0., 0., 0.],
       [9., 0., 0., 0.]])

让我们看一下 the offending __setitem__(我将省略很多不会被调用的代码):

row, col = self._validate_indices(key)

这很好 - row = [1, 2]col = 0

col = np.atleast_1d(col)
i, j = _broadcast_arrays(row, col)

到目前为止一切顺利 - i = [1, 2]j = [0, 0]

if i.ndim == 1:
# Inner indexing, so treat them like row vectors.
    i = i[None]
    j = j[None]

broadcast_row = x.shape[0] == 1 and i.shape[0] != 1
broadcast_col = x.shape[1] == 1 and i.shape[1] != 1

这是我们的问题 - ij 都变成了形状为 (1, 2) 的行向量。 x 这是您要分配的内容 (b[[1,2], 0]),其形状为 (2, 1);下一步引发 ValueError 原因 x 并且索引不对齐。

>>> c[[1,2], 0] = b[[1,2], 0].A

ValueError: cannot reshape array of size 4 into shape (2,)

这是同样的问题,但是 __setitem__x 广播到 (2,2) 数组中,然后再次失败,因为它比您分配给它的数组大。

解决方法 (b[[1,2], [0]]) 的形状 (1, 2) 不正确,但该错误最终抵消了索引 c.

中的错误

我不确定这个索引代码背后的确切逻辑是什么,所以我不确定如何在不引入其他细微错误的情况下解决这个问题。