首页 > 解决方案 > Numpy:基于单独的向量交换二维数组的位置

问题描述

假设我有一个 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

你怎么能做到这一点?

标签: pythonarraysnumpymatrix

解决方案


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]

这里可以省略副本的原因是因为

  1. 在赋值中,在赋值给左边的变量之前,右边会被完全评估。
  2. Numpy 的精美索引(A[r, c]这里)返回一个副本,而不像 slices(A[:, 0])返回一个视图。

因此,这行新代码所说的是

  1. 获取第一列的视图(即引用)A
  2. 创建A[r, c]. 由于 Numpy 数组的精美索引,副本是隐式的。
  3. 分配使用该列视图A[r, c]的第一列的值。A
  4. 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]

推荐阅读