首页 > 解决方案 > 使用花式索引修改空间矩阵

问题描述

我正在尝试使用精美的索引来修改大型空间矩阵。假设您有以下代码:

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 数组,这通常有效。我将不胜感激任何帮助。

标签: pythonnumpyscipysparse-matrix

解决方案


是的,这是 sparse 的错误__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.]])

让我们来看看有问题__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

这是我们的问题 -i两者j都变成了 shape 的行向量(1, 2)x这是您要分配的 ( b[[1,2], 0]),它是 shape (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)不正确,但该错误最终会抵消 indexing 中的错误c

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


推荐阅读