Словарь рейтинга Python

У меня есть словарь Python:

x = {'a':10.1,'b':2,'c':5}

Как мне заняться ранжированием и возвратом значения ранга? Как вернуться

res = {'a':1,c':2,'b':3}

Спасибо

Редактировать:

Я не пытаюсь сортировать, как это может быть сделано с помощью sorted функция в питоне. Я больше думал о получении значений ранга от самого высокого до самого маленького... поэтому заменил значения словаря их позицией после сортировки. 1 означает самый высокий и 3 означает самый низкий.

8 ответов

Если я правильно понимаю, вы можете просто использовать sorted чтобы получить заказ, а затем enumerate нумеровать их:

>>> 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}

Обратите внимание, что это предполагает, что ранги однозначны. Если у вас есть связи, порядок ранжирования среди связанных ключей будет произвольным. Это тоже легко сделать, используя аналогичные методы, например, если вы хотите, чтобы все связанные ключи имели одинаковый ранг. У нас есть

>>> 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}

но

>>> 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}

Использование 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 имеет некоторые другие "методы" для связей, которые могут быть более подходящими для того, что вы хотите делать со связями.

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)])

Довольно простой вид простого, но сложного однострочного.

{key[0]:1 + value for value, key in enumerate(
                       sorted(d.iteritems(),
                              key=lambda x: x[1],
                              reverse=True))}

Позволь мне провести тебя через это.

  • Мы используем enumerate чтобы дать нам естественный порядок элементов, который начинается с нуля. Просто используя enumerate(d.iteritems()) создаст список кортежей, которые содержат целое число, затем кортеж, который содержит пару ключ: значение из исходного словаря.
  • Мы сортируем список так, чтобы он отображался в порядке убывания.
  • Мы хотим обработать значение как перечисляемое значение (то есть, мы хотим, чтобы 0 было значением для "a", если есть только одно вхождение (и я немного нормализую это), и т. Д.), И мы хотим, чтобы ключ был фактическим ключом из словаря. Итак, здесь мы меняем порядок, в котором мы связываем два значения.
  • Когда приходит время извлечь фактический ключ, он все еще находится в форме кортежа - он выглядит как ('a', 0)поэтому мы хотим получить только первый элемент из этого. key[0] выполняет это.
  • Когда мы хотим получить фактическое значение, мы нормализуем его ранжирование так, чтобы оно основывалось на 1, а не на нуле, поэтому мы добавляем 1 к value,

Одним из способов было бы проверить словарь на предмет наибольшего значения, а затем удалить его при создании нового словаря:

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

Сначала сортируйте по значению в dict, затем присваивайте ранги. Убедитесь, что вы сортируете в обратном порядке, а затем воссоздайте диктат с разрядами.

из предыдущего ответа:

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

Вы могли бы сделать это,

>>> x = {'a':10.1,'b':2,'c':5}
>>> m = {}
>>> k = 0
>>> for i in dict(sorted(x.items(), key=lambda k: k[1], reverse=True)):
        k += 1
        m[i] = k


>>> m
{'a': 1, 'c': 2, 'b': 3}

Использование панд:

      import pandas as pd

x = {'a':10.1,'b':2,'c':5}
res = dict(zip(x.keys(), pd.Series(x.values()).rank().tolist()))
Другие вопросы по тегам