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
的值复制到另一个数组res
。 res1
显示了实现它的 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
为什么我不能从另一个矩阵分配矩阵的索引部分的值?让我们看看下面的代码示例:
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
的值复制到另一个数组res
。 res1
显示了实现它的 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