NumPy数组索引2D矩阵

5

我在处理大数据时遇到了一些问题。但现在,让我们假设我有一个用零填充的NumPy数组。

>>> x = np.zeros((3,3))
>>> x
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])

现在我想把一些零值改成具体的数据,我已经给出了我想要更改的单元格的索引。

>>> y = np.array([[0,0],[1,1],[2,2]])
>>> y 
array([[0, 0],
       [1, 1],
       [2, 2]])

我有一个数组,包含所需的(目前是随机的)数字,如下:

>>> z = np.array(np.random.rand(3))
>>> z
array([ 0.04988558,  0.87512891,  0.4288157 ])

现在我想我可以这样做:

>>> x[y] = z

但是它会像这样填充整个数组
>>> x
array([[ 0.04988558,  0.87512891,  0.4288157 ],
       [ 0.04988558,  0.87512891,  0.4288157 ],
       [ 0.04988558,  0.87512891,  0.4288157 ]])

But I was hoping to get

>>> x
array([[ 0.04988558,           0,          0 ],
       [          0,  0.87512891,          0 ],
       [          0,           0,  0.4288157 ]])

编辑

现在我使用的是对角线索引,但如果我的索引不仅仅是对角线呢?我希望以下方法可以实现:

>>> y = np.array([[0,1],[1,2],[2,0]])
>>> x[y] = z
>>> x
>>> x
array([[          0,  0.04988558,          0 ],
       [          0,           0, 0.87512891 ],
          0.4288157,           0,          0 ]])

但是它会像上面一样填充整个数组。

索引是从零开始的。也许您想更改元素[0,0][1,1][2,2] - BrenBarn
BrenBarn的方案可行。你可能想把 y[z]=a 改成 x[y]=z - dlangenk
已经按照您说的更改了,但是现在正在将整个数组都填充为更改后的内容。 - Mattijn
我曾经有一个类似的问题,Jaime 给出了答案,解释说(作为一般规则),多维数组应该使用元组进行索引。 - Jan Kuiken
1个回答

9

多维数组的数组索引有些不同。

如果你有一个向量,你可以通过使用以下方式访问前三个元素:

x[np.array([0,1,2])]

但是当你在矩阵上使用它时,它将返回前几行。乍一看,使用

x[np.array([0,0],[1,1],[2,2]])]

听起来很合理。然而,NumPy数组索引的工作方式不同:它仍然将所有这些索引视为1D方式,但返回与索引向量相同形状的向量中的值。

要正确访问2D矩阵,您必须将两个组件拆分为两个单独的数组:

x[np.array([0,1,2]), np.array([0,1,2])]

这将获取您的矩阵上所有主对角线的元素。使用此方法也可以进行赋值:
x[np.array([0,1,2]), np.array([0,1,2])] = 1

所以要访问您在编辑中提到的元素,您需要执行以下操作:

x[np.array([0,1,2]), np.array([1,2,0])]

1
我很高兴我的猜测听起来至少是合理的。但非常感谢您的明确答复,您是完全正确的。 - Mattijn
NumPy在复杂索引方面非常高效。你是指超出RAM大小的可扩展性吗?NumPy并不适合于外存计算。但这不是本回答的范围,请考虑打开一个适当的SO问题,如果你有一个。 - Nils Werner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接