我有一个我要排名的数字列表,从1(最高)开始,然后打印出来。对于有关系的数字,我只想按顺序编号,以先到者为准。
lst = [[0.0] , [0.0] , [0.0] , [0.1] , [0.2]]
#expected output
rank_lst = [3,4,5,2,1]
我只想要一个简单的功能,类似于我所做的事情:
rank_lst = [sorted(lst).index(values) for values in lst]
但是此值从0开始,将最低的数字列为0,并按如下所示对具有相同数字的并列值进行排名:
#output
rank_list = [0,0,0,1,2]
答案 0 :(得分:4)
您可以使用numpy.argsort()
由于要从高到低排序,因此可以先将值设为负。
import numpy as np
lst = [[0.0] , [0.0] , [0.0] , [0.1] , [0.2]]
np_lst = np.array([v[0] for v in lst])
rank_lst = list(np.argsort(np.argsort(-np_lst)) + 1)
编辑:再输入np.argsort()
即可获得所需的内容。
答案 1 :(得分:3)
您可以尝试使用collections.defaultdict
反向收集列表的索引,然后使用collections.deque
一次将索引从左侧索引中弹出。
from collections import defaultdict
from collections import deque
lst = [0, 1, 0, 2, 0]
d = defaultdict(deque)
for i, x in enumerate(sorted(lst, reverse=True), start=1):
d[x].append(i)
result = [d[x].popleft() for x in lst]
print(result)
# [3, 2, 4, 1, 5]
或者使用嵌套列表,如问题中所示:
from collections import defaultdict
from collections import deque
from operator import itemgetter
lst = [[0.0], [0.0], [0.0], [0.1], [0.2]]
single = list(map(itemgetter(0), lst))
d = defaultdict(deque)
for i, x in enumerate(sorted(single, reverse=True), start=1):
d[x].append(i)
result = [d[x].popleft() for x in single]
print(result)
# [3, 4, 5, 2, 1]
答案 2 :(得分:3)
您可以这样做
lst = [[0.0], [0.0], [0.0], [0.1], [0.2]]
# wanted: rank_lst == [3, 4, 5, 2, 1]
# add original position
data = list(enumerate(lst, start=1))
# -> [(1, [0.0]), (2, [0.0]), (3, [0.0]), (4, [0.1]), (5, [0.2])]
# sort by value
data = list(sorted(data, key=lambda x: x[1], reverse=True))
# -> [(5, [0.2]), (4, [0.1]), (1, [0.0]), (2, [0.0]), (3, [0.0])]
# add sorted position
data = list(enumerate(data, start=1))
# -> [(1, (5, [0.2])), (2, (4, [0.1])), (3, (1, [0.0])), (4, (2, [0.0])), (5, (3, [0.0]))]
# resort to original order
data = list(sorted(data, key=lambda x: x[1][0]))
# -> [(3, (1, [0.0])), (4, (2, [0.0])), (5, (3, [0.0])), (2, (4, [0.1])), (1, (5, [0.2]))]
# extract sorted order number
rank_lst = [x[0] for x in data]
# -> [3, 4, 5, 2, 1]
当然,您可以排除所有对list
的呼叫。我只用它们来创建输出。
答案 3 :(得分:-1)
那呢?
input = [[0.0], [0.0], [0.0], [0.1], [0.2]]
ranked_list = [item[0] for item in sorted([[index, value] for index, value in enumerate(a)], key=lambda x: x[1], reverse=True)]
final_list = [None] * len(input)
i = 1
for rank in ranked_list:
final_list[rank] = i
i += 1
输出:[3, 4, 5, 2, 1]
它在列表上使用enumerate
,然后按值(相反)对其进行排序,然后使用列表理解将索引放在新列表中。最后,创建一个len(input)
位置的空列表,并用输入的每个值的等级填充它。
编辑:现在实际上已经解决了所提出的问题,对不起您的误解
答案 4 :(得分:-1)
>>> lst = [[0.0] , [0.0] , [0.0] , [0.1] , [0.2]]
>>> lst1 = [i[0] for i in lst] # you only need numbers, not lists for each value
>>> xx = list(enumerate(lst1)) # add an "index" to each value
>>> xx.sort(key=lambda i: -i[1]) # sort on values
>>> xxx = [(i[0], i[1], j+1) for j, i in enumerate(xx)] # add the rank of each value
>>> xxx.sort(key=lambda i : i[0]) # put them back in the original order using the index
>>> res = [i[2] for i in xxx] # get just the ranks
>>> res
[3, 4, 5, 2, 1]