【问题标题】:Numpy: Why can'I assign a matrix to another matrix's indexed part?Numpy:为什么我不能将一个矩阵分配给另一个矩阵的索引部分?
【发布时间】:2020-10-20 17:06:18
【问题描述】:

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

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)。首先创建索引坐标的网格网格,然后使用元组索引,例如分配一长串点。

但是为什么呢?这背后的numpy 逻辑是什么?有没有类似的错误点?任何人都可以解释这一点!

【问题讨论】:

  • res2[indices, ...] 是副本,而不是视图。
  • 也许您的意思是视图,而不是副本?但是为什么 res2[:n] 和 res2[indices] 是不同的?

标签: python numpy matrix indexing variable-assignment


【解决方案1】:

当你这样做时:

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

res2[indices, ...] 部分创建一个独立于res2 的新数组,因为您使用的是advanced indexing。后面的位 [:, indices] = X 会将值分配给该新数组,而不是 res2。要实现你想要的,你可以使用np.ix_

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 2021-05-01
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    相关资源
    最近更新 更多