在numpy数组中交换列?

时间:2011-02-01 01:10:42

标签: python numpy

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-d数组只能使用单个()或一个新轴列表(和一个...)作为索引”,这意味着参数不是整数?我已经尝试将cols转换为int但是没有解决它。

4 个答案:

答案 0 :(得分:89)

这里有两个问题。第一个是你传递给函数的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 basic slicing不会创建实际数据的副本,而是创建相同数据的视图。要使其工作,您必须明确复制

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

或使用advanced slicing

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

答案 1 :(得分:23)

我发现以下内容最快:

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

答案 2 :(得分:12)

建立@Sven的回答:

import numpy as np
my_array = np.arange(9).reshape(3, 3)
print my_array

[[0 1 2]
 [3 4 5]
 [6 7 8]]

def swap_cols(arr, frm, to):
    arr[:,[frm, to]] = arr[:,[to, frm]]

swap_cols(my_array, 0, 1)
print my_array

[[1 0 2]
 [4 3 5]
 [7 6 8]]

def swap_rows(arr, frm, to):
    arr[[frm, to],:] = arr[[to, frm],:]

my_array = np.arange(9).reshape(3, 3)
swap_rows(my_array, 0, 2)
print my_array

[[6 7 8]
 [3 4 5]
 [0 1 2]]

答案 3 :(得分:4)

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

col1 = 0
col2 = 1    
my_array.T[[col1, col2]] = my_array.T[[col2, col1]]

这是交换列的一种非常优雅的方式:

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

结果:

WITH X AS (
    SELECT Vendor , SUM(MonthlyAmt) AS TotalAmtCalculated
    FROM VendorTable
    GROUP BY Vendor
)
UPDATE t 
 SET t.TotalAmt = x.TotalAmtCalculated
FROM VendorTable t 
INNER JOIN x ON t.Vendor = x.Vendor