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]])
为什么有效:
如果您在分配中b
使用两个numpy 数组进行索引,
b[x, y] = z
然后将 NumPy 想象为同时在 的每个元素x
和每个y
元素上移动z
(我们称它们为xval
,yval
和zval
),并将值分配给 b[xval, yval] zval
。当是一个常数,“每次z
移动只是返回相同的值。z
这就是我们想要的,x
成为 的第一列a
和y
第二列a
。因此,选择x = a[:, 0]
和y = a[:, 1]
。
b[a[:,0], a[:,1]] = 10
为什么b[a] = 10
不起作用
当您编写 时b[a]
,将 NumPy 视为通过移动 , 的每个元素a
(让我们称其为每个元素idx
)并将新数组中的值放入 in 的位置b[idx]
来创建一个新数组。idx
a
idx
是 中的一个值a
。所以它是一个int32。 b
是形状 (6,3),所以b[idx]
是一排b
形状 (3,)。例如,什么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 正在创建一个新数组,方法是在新数组中移动 in 的每个元素a
并将 in 的值放入新数组b[idx]
中。随着移动,将创建一个形状数组 (6,2)。但由于它本身的形状为 (3,),因此在 (6,2) 形状的数组中的每个位置,都会放置一个 (3,) 形状的值。结果是一个形状数组 (6,2,3)。idx
a
idx
a
b[idx]
现在,当你做一个像
b[a] = 10
创建一个具有值的临时形状 (6,2,3) 数组b[a]
,然后执行分配。由于 10 是一个常数,因此该赋值将值 10 放置在 (6,2,3) 形数组中的每个位置。然后将临时数组中的值重新分配回b
. 请参阅对文档的参考。因此 (6,2,3) 形数组中的值被复制回 (6,3) 形b
数组。值相互覆盖。但重点是你没有得到你想要的任务。