使用特定索引中的值创建一个 numpy 矩阵

create a numpy matrix of with values in specific indexes

arr = np.zeros(5)
indexes = np.array([1, 3])
values = np.array([10, 20])
arr[indexes] = values

所以我得到这个数组:

>>> arr
array([ 0., 10.,  0., 20.,  0.])

如果我想要以下矩阵:

>>> mat
array([[ 1,  0,  2,  0,  0],
       [ 0,  3,  0,  4,  0],
       [ 0,  5,  0,  0,  6],
       [ 7,  0,  8,  0,  0],
       [ 0,  9,  0,  0, 10]])

我尝试使用此代码:

mat = np.zeros((5, 5))
indexes = np.array([[0, 2], [1, 3], [1, 4], [0, 2], [1, 4]])
values = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])

当我尝试执行这段代码时:

mat[indexes] = values

我收到以下错误:

ValueError: shape mismatch: value array of shape (5,2) could not be broadcast to indexing result of shape (5,2,5)

我做错了什么?

查看 Numpy documentation on indexing 专门索引多维数组。

What am I doing wrong?

import numpy as np

mat = np.zeros((5, 5))
indexes = np.array([[0, 2], [1, 3], [1, 4], [0, 2], [1, 4]])
print(mat[indexes])

给出:

[[[0. 0. 0. 0. 0.]  # row 0
  [0. 0. 0. 0. 0.]] # row 2

 [[0. 0. 0. 0. 0.]  # row 1
  [0. 0. 0. 0. 0.]] # row 3

 [[0. 0. 0. 0. 0.]  # ...
  [0. 0. 0. 0. 0.]]

 [[0. 0. 0. 0. 0.]
  [0. 0. 0. 0. 0.]]

 [[0. 0. 0. 0. 0.]
  [0. 0. 0. 0. 0.]]]

然后您试图将大小为 (5, 2) 的数组分配给此切片,因此出现不匹配错误。

解决方案:

import numpy as np

mat = np.zeros((5, 5))
indicies = np.array([0, 0, 1, 1, 2, 2, 3, 3, 4, 4]), np.array([0, 2, 1, 3, 1, 4, 0, 2, 1, 4])
values = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
mat[indicies] = values
print(mat)

给出:

[[ 1.  0.  2.  0.  0.]
 [ 0.  3.  0.  4.  0.]
 [ 0.  5.  0.  0.  6.]
 [ 7.  0.  8.  0.  0.]
 [ 0.  9.  0.  0. 10.]]

要对大小为 (5, 5) 的数组进行切片,我们可以使用两个数组。第一个数组本质上代表行索引位置,而第二个数组本质上代表列索引位置。这会产生一个形状 (1, 10) 的切片,我们可以将我们的值赋给它。

您需要指定行和列来对矩阵进行切片

import numpy as np

mat = np.zeros((5, 5))
indexes = np.array([[0, 2], [1, 3], [1, 4], [0, 2], [1, 4]])
values = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])

for row_i, column_indices in enumerate(indexes):
    mat[row_i, column_indices] = values[row_i]

print(mat)
>> array([[ 1.,  0.,  2.,  0.,  0.],
          [ 0.,  3.,  0.,  4.,  0.],
          [ 0.,  5.,  0.,  0.,  6.],
          [ 7.,  0.,  8.,  0.,  0.],
          [ 0.,  9.,  0.,  0., 10.]])

或者不用for循环赋值:

rows = np.indices((mat.shape[0],)).reshape(-1, 1)
mat[rows, indexes] = values
print(mat)
>> array([[ 1.,  0.,  2.,  0.,  0.],
          [ 0.,  3.,  0.,  4.,  0.],
          [ 0.,  5.,  0.,  0.,  6.],
          [ 7.,  0.,  8.,  0.,  0.],
          [ 0.,  9.,  0.,  0., 10.]])