【问题标题】:Numpy: swap positions of 2D array based on a separate vectorNumpy:基于单独的向量交换二维数组的位置
【发布时间】:2018-09-17 01:03:45
【问题描述】:

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

你怎么能做到这一点?

【问题讨论】:

  • x[[0, 1, 2], [2, 1, 1]], x[[0, 1, 2], [0, 0, 0]] = x[[0, 1, 2], [0, 0, 0]], x[[0, 1, 2], [2, 1, 1]]

标签: python arrays numpy matrix


【解决方案1】:
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 的第一列的值分配A[r, c] 该列的视图。
  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]

【讨论】:

  • 甚至更短的A[r, c], A[:, 0] = A[:, 0], A[r, c] 使用A[r, c] 无论如何都会复制的事实。
  • @PaulPanzer No. A[:, 0] 返回一个视图,因为它是一个切片,所以副本是必要的。
  • @PaulPanzer 哦,是的,你是对的。忽略我之前的评论。我没有看到你交换了分配顺序。
【解决方案2】:
a= np.array([[0,1,2],[2,0,1],[1,2,0]])
b=[2,1,1]
for rc, r in enumerate(a):
    r[0], r[b[rc]] =  r[b[rc]], r[0]
print(a)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 2021-07-24
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多