对数字列表进行排名

Chr*_*rgo 2 python scipy python-2.7

我有一个清单:

 somelist = [500, 600, 200, 1000]
Run Code Online (Sandbox Code Playgroud)

我想生成该列表的排名顺序:

 rankorderofsomelist = [3, 2, 4, 1]
Run Code Online (Sandbox Code Playgroud)

一些复杂的解决方案,但有人有任何简单的方法吗?

DSM*_*DSM 7

既然您已经标记了这个问题scipy,您可以使用scipy.stats.rankdata

>>> rankdata(somelist)
array([ 2.,  3.,  1.,  4.])
>>> len(somelist) - rankdata(somelist)
array([ 2.,  1.,  3.,  0.])
>>> len(somelist) - rankdata(somelist) + 1
array([ 3.,  2.,  4.,  1.])
Run Code Online (Sandbox Code Playgroud)

真正的优点是您可以指定如何处理极端情况:

>>> rankdata([0,1,1,2])
array([ 1. ,  2.5,  2.5,  4. ])
>>> rankdata([0,1,1,2], method='min')
array([ 1,  2,  2,  4])
>>> rankdata([0,1,1,2], method='dense')
array([ 1,  2,  2,  3])
Run Code Online (Sandbox Code Playgroud)


Ale*_*lli 5

我能想到的最简单的:

rankorder = sorted(range(len(thelist)), key=thelist.__getitem__)
Run Code Online (Sandbox Code Playgroud)

这当然会产生[2, 1, 3, 0],因为 Python 索引总是从零开始的——如果出于某种绝对奇怪的原因你需要为每个索引添加一个,你当然可以很容易地这样做:

rankorder_weird = [1+x for x in rankorder]
Run Code Online (Sandbox Code Playgroud)


New*_*ewb 5

试试这个单行:

rankorderofsomelist = [sorted(somelist).index(x) for x in somelist]
Run Code Online (Sandbox Code Playgroud)

请注意,对于具有相同值的多个条目的列表,它的行为将符合预期(例如,相同值的四个实例,它们都是列表中的第二大实例,将全部排名为 2)。另请注意,Pythonic 排序是升序(从小到大)且从零开始的,因此您可能必须对列表应用最后一次遍历以增加排名、反转排名等。

您可以将该传球包含在一行中。要产生您想要的结果,只需使用:

rankorderofsomelist = [len(somelist)-(sorted(somelist).index(x)) for x in somelist]
Run Code Online (Sandbox Code Playgroud)

  • 如果我没有记错的话,这具有 N^3log(N) 复杂性:对于列表中的每个项目,您都对列表进行排序,然后线性搜索该特定项目。即使您之前对列表进行排序,而不是在循环中排序,您仍然会看到 N^2 复杂度。你[可以做得更糟](http://c2.com/cgi/wiki?SlowSort),但你必须非常努力。这是一个糟糕的建议。-1,恐怕... (2认同)