Skip to content Skip to sidebar Skip to footer

Python Ranking Dictionary Return Rank

I have a python dictionary: x = {'a':10.1,'b':2,'c':5} How do I go about ranking and returning the rank value? Like getting back: res = {'a':1,c':2,'b':3} Thanks Edit: I am not tr

Solution 1:

If I understand correctly, you can simply use sorted to get the ordering, and then enumerate to number them:

>>> x = {'a':10.1, 'b':2, 'c':5}
>>> sorted(x, key=x.get, reverse=True)
['a', 'c', 'b']
>>> {key: rank for rank, key in enumerate(sorted(x, key=x.get, reverse=True), 1)}
{'b': 3, 'c': 2, 'a': 1}

Note that this assumes that the ranks are unambiguous. If you have ties, the rank order among the tied keys will be arbitrary. It's easy to handle that too using similar methods, for example if you wanted all the tied keys to have the same rank. We have

>>> x = {'a':10.1, 'b':2, 'c': 5, 'd': 5}
>>> {key: rank for rank, key in enumerate(sorted(x, key=x.get, reverse=True), 1)}
{'a': 1, 'b': 4, 'd': 3, 'c': 2}

but

>>> r = {key: rank for rank, key in enumerate(sorted(set(x.values()), reverse=True), 1)}
>>> {k: r[v] for k,v in x.items()}
{'a': 1, 'b': 3, 'd': 2, 'c': 2}

Solution 2:

Using scipy.stats.rankdata:

[ins] In [55]: from scipy.stats import rankdata                                                                                                                                                        

[ins] In [56]: x = {'a':10.1, 'b':2, 'c': 5, 'd': 5}                                                                                                                                                   

[ins] In [57]: dict(zip(x.keys(), rankdata([-i for i in x.values()], method='min')))                                                                                                                   
Out[57]: {'a': 1, 'b': 4, 'c': 2, 'd': 2}

[ins] In [58]: dict(zip(x.keys(), rankdata([-i for i in x.values()], method='max')))                                                                                                                   
Out[58]: {'a': 1, 'b': 4, 'c': 3, 'd': 3}

@beta, @DSM scipy.stats.rankdata has some other 'methods' for ties also that may be more appropriate to what you are wanting to do with ties.


Solution 3:

First sort by value in the dict, then assign ranks. Make sure you sort reversed, and then recreate the dict with the ranks.

from the previous answer :

import operator
x={'a':10.1,'b':2,'c':5}
sorted_x = sorted(x.items(), key=operator.itemgetter(1), reversed=True)
out_dict = {}
for idx, (key, _) in enumerate(sorted_x):
    out_dict[key] = idx + 1
print out_dict

Solution 4:

One way would be to examine the dictionary for the largest value, then remove it, while building a new dictionary:

my_dict = x = {'a':10.1,'b':2,'c':5}
i = 1
new_dict ={}
while len(my_dict) > 0:
    my_biggest_key = max(my_dict, key=my_dict.get)
    new_dict[my_biggest_key] = i
    my_dict.pop(my_biggest_key)
    i += 1
print new_dict

Solution 5:

In [23]: from collections import OrderedDict

In [24]: mydict=dict([(j,i) for i, j in enumerate(x.keys(),1)])

In [28]: sorted_dict = sorted(mydict.items(), key=itemgetter(1))

In [29]: sorted_dict
Out[29]: [('a', 1), ('c', 2), ('b', 3)]
In [35]: OrderedDict(sorted_dict)
Out[35]: OrderedDict([('a', 1), ('c', 2), ('b', 3)])

Post a Comment for "Python Ranking Dictionary Return Rank"