Numpy:为什么我不能将一个矩阵分配给另一个矩阵的索引部分?

Numpy: Why can'I assign a matrix to another matrix's indexed part?

为什么我不能从另一个矩阵分配矩阵的索引部分的值?让我们看看下面的代码示例:

n, m = 5, 10
X = np.random.randint(0, 10, (n, n))
indices = np.random.randint(0, m, (n,))

res1 = np.zeros((m, m))
res2 = np.zeros((m, m))
res3 = np.zeros((m, m))

for i in range(n):
    for j in range(n):
        res1[indices[i], indices[j]] = X[i, j]

res2[:n, :n] = X # ========================================================
(res2[:n, :n] == X).all() # ===============================================
# True (assign to continuous blocks is ok)

res2[indices, ...][:, indices] = X  # directly index from array and assign value
(res2 == res1).all()
# False, res2 stays all-zero

row_mat, col_mat = np.meshgrid(indices, indices)[::-1]
points_arr = np.stack([np.ravel(row_mat), np.ravel(col_mat)]).T
rows, cols = zip(*points_arr)
res3[rows, cols] = X.flatten()
(res3==res1).all()
# True

上面代码中的玩具示例是通过坐标到坐标映射将一个数组X的值复制到另一个数组resres1 显示了实现它的 for 循环。我们都熟悉注释为====的表达式,其中连续块的值可以联合赋值(它在内存中真的是“连续的”吗?)。但是这不适用于枚举索引,如res2所示。 copy.deepcopy 也不行。

是的,我找到了实现此目的的方法(如 res3)。首先创建索引坐标的 meshgrid,然后使用元组索引就像分配一长串点。

但是为什么呢?这背后的 numpy 逻辑是什么?有没有类似的错误点?谁能解释一下,我们将不胜感激!

当你这样做时:

res2[indices, ...][:, indices] = X

部分 res2[indices, ...] 创建了一个独立于 res2 的新数组,因为您正在使用 advanced indexing. The later bit [:, indices] = X will assign values to that new array, not to res2. To achieve what you want, you can use np.ix_:

res2[np.ix_(indices, indices)] = X