【问题标题】:Swapping columns in a numpy array?交换numpy数组中的列?
【发布时间】:2011-06-18 23:30:36
【问题描述】:
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 数组只能使用单个 () 或 newaxes 列表(和单个 ...)作为索引”,这意味着参数不是整数?我已经尝试将 cols 转换为 int 但这并没有解决它。

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    这里有两个问题。首先是您传递给函数的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]]
    

    【讨论】:

    • 高级切片似乎也不会复制数据。
    • @MateenUlhaq 请放心,确实如此。请参阅链接文档,或自行尝试。
    【解决方案2】:

    我发现以下最快:

    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
    

    【讨论】:

    • 赞成 copy() 部分,我的代码中缺少这个。
    【解决方案3】:

    以@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]]
    

    【讨论】:

      【解决方案4】:

      在 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.]])
      

      【讨论】:

      • 确实非常优雅和聪明。谢谢。
      【解决方案5】:

      如果您想同时交换列并分配给一个新变量,我能想到的最简洁明了的方法是:

      import numpy as np
      test_arr = np.arange(12).reshape(4,3)
      swapped = np.concatenate((test_arr[:, [1,0]], test_arr[:, 2:]), axis=1)
      

      注意,如果其他列不存在,它将连接一个空数组,这意味着它只会交换前两列。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-23
        • 2013-02-02
        • 2014-07-19
        • 2014-05-15
        • 2015-04-22
        • 2019-04-22
        • 2017-03-08
        相关资源
        最近更新 更多