【问题标题】:Getting indices of ascending order of list获取列表升序的索引
【发布时间】:2019-06-20 16:29:25
【问题描述】:

我知道这个问题已经被问了一百次了,但答案似乎总是“使用 numpy 的 argsort”。但要么我误解了大多数人在问什么,要么答案对这个问题不正确。无论如何,我希望获得列表升序的索引。措辞令人困惑,例如,给定一个列表[4, 2, 1, 3],我希望得到一个返回列表[3, 1, 0, 2]。最小的项目是1,所以它得到索引0,最大的项目是4,所以它得到索引3。在我看来,argsort 似乎经常被建议,但它似乎并没有这样做。

from numpy import argsort

l = [4, 2, 1, 3]
print(argsort(l))
# [2, 1, 3, 0]
# Expected [3, 1, 0, 2]

显然 argsort 正在做其他事情,那么它实际上在做什么,它与预期的行为有何相似之处,因此经常(错误地)建议它?而且,更重要的是,我怎样才能得到想要的输出?

【问题讨论】:

  • Docs say 返回对数组进行排序的索引。
  • @KeyurPotdar 没错,但你会期待[3, 1, 0, 2],不是吗?
  • 否 - 它会将 索引 返回到原始列表中,因此如果您按照应用于原始列表的顺序使用它们,则列表将被排序:[ l[ 2 ], l[ 1 ], l[ 3 ], l[ 0 ]] 是排序列表
  • 不,[2, 1, 3, 0] 指向 l[2], l[1], l[3], l[0] 即 [1, 2, 3, 4 ]
  • 试试argsort(argsort(l))

标签: python python-3.x list numpy sorting


【解决方案1】:

argsoft() 基本上是将您的列表转换为已排序的索引列表。

l = [4, 2, 1, 3]

首先它获取列表中每个元素的索引,因此新列表变为:

indexed=[0, 1, 2, 3]

然后它根据原始列表中的项目对索引列表进行排序。如4:0 , 2:1 , 1:2 and 3:3,其中:表示“对应”。

对我们得到的原始列表进行排序

l=[1, 2, 3, 4]

并放置旧列表的每个对应索引的值

new=[2,1,3,0]

所以基本上它根据原始列表对列表的索引进行排序。这是据我了解的。对不起,如果我错了。

【讨论】:

    【解决方案2】:

    您没有得到“正确”或预期答案的原因是因为您问错了问题!

    您所追求的是排序后的元素 rank,而 Numpy 的 argsort() 返回排序后的索引列表,如文档所述!。这些不是一回事(正如您发现的那样;))!

    【讨论】:

      【解决方案3】:

      @hpaulj 正确回答了我,但在评论中。而你看不到他。 他的回答对我帮助很大,让我得到了我想要的。

      import numpy as np
      l = [4, 2, 1, 3]
      print(np.argsort(np.argsort(l)))
      

      返回:

      [3, 1, 0, 2]
      

      这是您所期望的。如果已排序,此方法返回数组的索引。

      ⚠️ 但是请注意,如果输入数组包含重复,那么会有一个有趣的效果:

      import numpy as np
      l = [4, 2, 1, 3, 4]
      print(np.argsort(np.argsort(l)))
      
      

      返回:

      [3 1 0 2 4]
      

      他可能不会伤害你,但他会伤害我。我这样解决这个问题:

      import numpy as np
      
      l = [4, 2, 1, 3, 4]
      
      ret2 = np.vectorize(lambda val: np.searchsorted(np.unique(l), val))(l)
      
      print('Returned', ret2)
      print('Expected', [3, 1, 0, 2, 3])
      
      

      返回:

      Returned [3 1 0 2 3]
      Expected [3, 1, 0, 2, 3]
      

      的确,由于vectorize 函数,我的解决方案会很慢。 但是没有什么能阻止您使用numba。不过我还没有测试过?。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多