【问题标题】:How to rearrange array based upon index array如何根据索引数组重新排列数组
【发布时间】:2014-11-29 10:09:52
【问题描述】:

我正在寻找一种可以帮助我执行以下操作的单行解决方案。

假设我有

array = np.array([10, 20, 30, 40, 50])

我想根据输入顺序重新排列它。如果有一个名为 arrange 的 numpy 函数,它将执行以下操作:

newarray = np.arrange(array, [1, 0, 3, 4, 2])
print newarray

    [20, 10, 40, 50, 30]

形式上,如果要重新排序的数组是 m x n,而“index”数组是 1 x n,则排序将由名为“index”的数组确定。

numpy有这样的功能吗?

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    对于那些有同样困惑的人,我实际上正在寻找一个稍微不同版本的“基于索引重新排列数组”。在我的情况下,索引数组正在索引目标数组而不是源数组。换句话说,我试图根据它在新数组中的位置重新排列一个数组。

    在这种情况下,只需在索引之前应用argsort。例如

    >>> arr = np.array([10, 20, 30, 40, 50])
    >>> idx = [1, 0, 3, 4, 2]
    >>> arr[np.argsort(idx)]
    array([20, 10, 50, 30, 40])
    

    请注意此结果与 op 所需结果之间的差异。

    可以来回验证

    >>> arr[np.argsort(idx)][idx] == arr
    array([ True,  True,  True,  True,  True])
    >>> arr[idx][np.argsort(idx)] == arr
    array([ True,  True,  True,  True,  True])
    

    【讨论】:

      【解决方案2】:

      如果你想按降序排序:

      a = np.array([1,2,3,4,5])
      np.argsort(a)
      > array([0, 1, 2, 3, 4])
      np.argsort(-a)
      > array([4, 3, 2, 1, 0])
      

      【讨论】:

        【解决方案3】:

        对于索引为二维数组的,可以使用map函数。 这是一个例子:

        a = np.random.randn(3, 3)
        print(a)
        print(np.argsort(a))
        
        print(np.array(list(map(lambda x, y: y[x], np.argsort(a), a))))
        

        输出是

        [[-1.42167035  0.62520498  2.02054623]
         [-0.17966393 -0.01561566  0.24480554]
         [ 1.10568543  0.00298402 -0.71397599]]
        [[0 1 2]
         [0 1 2]
         [2 1 0]]
        [[-1.42167035  0.62520498  2.02054623]
         [-0.17966393 -0.01561566  0.24480554]
         [-0.71397599  0.00298402  1.10568543]]
        

        【讨论】:

          【解决方案4】:

          您可以直接使用“索引”列表,也可以使用索引数组:

          >>> arr = np.array([10, 20, 30, 40, 50])
          >>> idx = [1, 0, 3, 4, 2]
          >>> arr[idx]
          array([20, 10, 40, 50, 30])
          

          如果idx 已经是ndarray 而不是list,它往往会快得多,即使它可以以任何一种方式工作:

          >>> %timeit arr[idx]
          100000 loops, best of 3: 2.11 µs per loop
          >>> ai = np.array(idx)
          >>> %timeit arr[ai]
          1000000 loops, best of 3: 296 ns per loop
          

          【讨论】:

          • 谢谢!如果“索引”是二维数组怎么办?例如,我想通过使用索引[[1,0], [0,1]][[1,2], ["a", "b"] 变成[[2,1], ["a", "b"]]。我知道一个丑陋的方法是使用 for 循环使用索引数组的相应行重新排列数组的每一行。但必须有更快的方法。
          • 注意:索引数组idx不能是元组。这有点违反直觉,但您的解决方案非常有效。谢谢
          • 我知道这是旧的,但我正在寻找相同的解决方案。线 arr[ai] 似乎根本没有效果。 python版本3.7.3
          猜你喜欢
          • 2017-04-08
          • 1970-01-01
          • 2020-11-13
          • 1970-01-01
          • 1970-01-01
          • 2019-12-11
          • 2015-02-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多