如何交换numpy数组中的列?

73 投票
5 回答
99263 浏览
提问于 2025-04-16 10:58
from numpy import *
def swap_columns(my_array, col1, col2):
    temp = my_array[:,col1]
    my_array[:,col1] = my_array[:,col2]
    my_array[:,col2] = temp

然后

swap_columns(data, 0, 1)

这样不行。不过,直接调用代码

temp = my_array[:,0]
my_array[:,0] = my_array[:,1]
my_array[:,1] = temp

是可以的。为什么会这样呢?我该怎么解决?错误信息说“IndexError: 0维数组只能用单个()或者一个新轴的列表(还有单个...)作为索引”,这意味着参数不是整数?我已经尝试把列转换成整数,但这并没有解决问题。

5 个回答

17

在NumPy中,交换列的优雅方法就像在Python中交换两个变量一样,写法是这样的:x, y = y, x

i, j = 0, 1
A.T[[i, j]] = A.T[[j, i]]  # swap the columns i and j

假设你有一个这样的numpy数组A

array([[ 0., -1.,  0.,  0.],
       [ 0.,  1.,  1.,  1.],
       [ 0.,  0., -1.,  0.],
       [ 0.,  0.,  0., -1.]])

使用A.T[[0, 1]] = A.T[[1, 0]]可以交换前两列:

array([[-1.,  0.,  0.,  0.],
       [ 1.,  0.,  1.,  1.],
       [ 0.,  0., -1.,  0.],
       [ 0.,  0.,  0., -1.]])
45

我发现以下方法是最快的:

my_array[:, 0], my_array[:, 1] = my_array[:, 1], my_array[:, 0].copy()

时间分析如下:

import numpy as np
my_array = np.arange(900).reshape(30, 30)

具体的时间分析结果是:

%timeit my_array[:, 0], my_array[:, 1] = my_array[:, 1], my_array[:, 0].copy()
The slowest run took 15.05 times longer than the fastest. This could mean that an intermediate result is being cached 
1000000 loops, best of 3: 1.72 µs per loop

高级切片的时间如下:

%timeit my_array[:,[0, 1]] = my_array[:,[1, 0]]
The slowest run took 7.38 times longer than the fastest. This could mean that an intermediate result is being cached 
100000 loops, best of 3: 6.9 µs per loop
130

这里有两个问题。第一个是你传给函数的 data 似乎不是一个二维的 NumPy 数组——至少错误信息是这么说的。

第二个问题是代码的运行结果和你预期的不一样:

my_array = numpy.arange(9).reshape(3, 3)
# array([[0, 1, 2],
#        [3, 4, 5],
#        [6, 7, 8]])
temp = my_array[:, 0]
my_array[:, 0] = my_array[:, 1]
my_array[:, 1] = temp
# array([[1, 1, 2],
#        [4, 4, 5],
#        [7, 7, 8]])

问题在于,NumPy 的 基本切片 并不会创建实际数据的副本,而只是对同一数据的一个视图。要让这个功能正常工作,你需要明确地复制数据

temp = numpy.copy(my_array[:, 0])
my_array[:, 0] = my_array[:, 1]
my_array[:, 1] = temp

或者使用 高级切片

my_array[:, [0, 1]] = my_array[:, [1, 0]]

撰写回答