假设我有一个 3x3 numpy 数组:
[[0, 1, 2],
[2, 0, 1],
[1, 2, 0]]
还有一个附加向量:
[2,
1,
1]
对于矩阵中的每一行,我想将第 0 个索引处的数字与向量中相应索引处的数字交换。在此示例中,交换后,最终输出将是:
[[2, 1, 0], # the 0th and 2nd positions have been swapped
[0, 2, 1], # the 0th and 1st positions have been swapped
[2, 1, 0]] # the 0th and 1st positions have been swapped
你怎么能做到这一点?
最佳答案
import numpy as np
A = np.asarray([[0, 1, 2],
[2, 0, 1],
[1, 2, 0]])
col_idxs = np.asarray([2, 1, 1])
row_idxs = np.arange(len(A))
a = A[:, 0].copy()
A[:, 0] = A[row_idxs, col_idxs]
A[row_idxs, col_idxs] = a
或者更简洁
c = np.asarray([2, 1, 1])
r = np.arange(len(A))
A[:, 0], A[r, c] = A[r, c], A[:, 0].copy()
这里我们利用这样一个事实:我们可以通过为相应的行和列索引提供两个单独的类似列表的对象来索引 numpy 数组的各个元素。
所以行 A[:, 0], A[r, c] = A[r, c], A[:, 0].copy()
可以理解为从每一列获取索引元素并将它们与第一列交换。
编辑
感谢 @Paul Panzer 的评论,通过将其写为 A[r, c], A[:, 0] = A[:, 0], A[r, c]
可以使作业变得更短。 .
注意分配给 A[r, c]
的顺序和A[:, 0]
与早期版本相比有所变化。
这里可以省略副本的原因是因为
- 在作业中,先对右侧进行全面评估 分配给左侧的变量。
- Numpy 的花式索引(
A[r, c]
这里)返回一个副本,这与 切片 (A[:, 0]
) 返回 View 。
因此,这行新代码的内容是
- 获取
A
第一列的 View (即引用) - 创建
A[r, c]
的副本。由于 Numpy 数组的奇特索引,该副本是隐式的。 - 分配
A[r, c]
A
第一列的值使用 该列的 View 。 - 指定
A
的第一列A[r, c]
的副本我们之前做的 (请注意,此时A[r, c]
已被分配给旧的A[:, 0]
的值.)
此外,我们不需要将索引转换为 Numpy 数组。
c = [2, 1, 1]
r = range(len(A))
A[r, c], A[:, 0] = A[:, 0], A[r, c]
关于python - Numpy:基于单独的向量交换二维数组的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52359612/