2D数组索引

41
我如何对用作索引的一些数组进行索引? 我有以下这样的2D数组:
array([
   [2, 0],
   [3, 0],
   [3, 1],
   [5, 0],
   [5, 1],
   [5, 2]
])

我想使用这个数组作为索引,并将值10放入一个新的空矩阵的相应索引中。输出应该如下所示:
array([
   [ 0,  0,  0],
   [ 0,  0,  0],
   [10,  0,  0],
   [10, 10,  0],
   [ 0,  0,  0],
   [10, 10, 10]
])

到目前为止,我已经尝试过这个-

from numpy import*
a = array([[2,0],[3,0],[3,1],[5,0],[5,1],[5,2]])
b = zeros((6,3), dtype ='int32')
b[a] = 10

但是这给出了错误的输出。

2个回答

66
In [1]: import numpy as np
In [2]: a = np.array([[2,0],[3,0],[3,1],[5,0],[5,1],[5,2]])
In [3]: b = np.zeros((6,3), dtype='int32')

In [4]: b[a[:,0], a[:,1]] = 10

In [5]: b
Out[5]: 
array([[ 0,  0,  0],
       [ 0,  0,  0],
       [10,  0,  0],
       [10, 10,  0],
       [ 0,  0,  0],
       [10, 10, 10]])

为什么它有效:

如果你使用两个numpy数组来对b进行索引赋值,

b[x, y] = z

那么,想象一下NumPy同时在每个元素上移动xyz(我们称它们为xvalyvalzval),并将b[xval, yval]的值赋值为zval。当z是一个常数时,“遍历z”只会每次返回相同的值。

这正是我们想要的,其中xa的第一列,ya的第二列。因此,选择x = a[:, 0]y = a[:, 1]

b[a[:,0], a[:,1]] = 10

为什么b[a] = 10不能工作

当你写b[a]时,可以将NumPy视为通过移动a的每个元素(我们称之为idx)并在新数组中将b[idx]的值放置在a中的idx位置来创建一个新数组。

idxa中的一个值。因此它是int32类型。 b的形状为(6,3),所以b[idx]是一个形状为(3,)的b行。例如,当idx

In [37]: a[1,1]
Out[37]: 0

b[a[1,1]]

In [38]: b[a[1,1]]
Out[38]: array([0, 0, 0])

那么

In [33]: b[a].shape
Out[33]: (6, 2, 3)
所以让我们再重复一遍:NumPy通过遍历数组a中的每个元素,并将b[idx]的值放置在新数组中,位置为idxa中的位置。当idx遍历a时,将会创建一个形状为(6,2)的数组。但是,由于b[idx]本身的形状为(3,),因此在(6,2)形状的数组的每个位置上,都会放置一个形状为(3,)的值。结果是一个形状为(6,2,3)的数组。

现在,当你执行像这样的赋值操作:

b[a] = 10
创建一个形状为(6,2,3)临时数组,其值为b[a],然后执行赋值操作。由于10是一个常数,该赋值将在(6,2,3)形状的数组中的每个位置上放置值10。 然后将临时数组中的值重新分配回b。参见文档引用。因此,(6,2,3)形状数组中的值被复制回(6,3)形状的b数组。值相互覆盖。但主要问题是您无法获得所需的赋值结果。

4
谢谢您的解释和见解。但实话实说,b[a]非常自然,遗憾的是numpy的设计者没有预见到以这种方式实现它。 - Evan Pu

1

您还可以转置索引数组a,将结果转换为元组并索引数组b并赋值。将索引数组转换为元组可确保多维索引按预期工作。

a = np.array([[2, 0], [3, 0], [3, 1], [5, 0], [5, 1], [5, 2]])
b = np.zeros((6,3), dtype ='int32')

b[tuple(a.T)] = 10
# or 
b[(*a.T,)] = 10
# or 
b[(*a.T.tolist(),)] = 10

它们都能够产生预期的输出

array([[ 0,  0,  0],
       [ 0,  0,  0],
       [10,  0,  0],
       [10, 10,  0],
       [ 0,  0,  0],
       [10, 10, 10]])

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