У меня есть список:Рейтинг списка номеров
somelist = [500, 600, 200, 1000]
Я хочу, чтобы сформировать заказ ранга этого списка:
rankorderofsomelist = [3, 2, 4, 1]
Есть some complex solutions, но есть ли какой-либо простые методы?
У меня есть список:Рейтинг списка номеров
somelist = [500, 600, 200, 1000]
Я хочу, чтобы сформировать заказ ранга этого списка:
rankorderofsomelist = [3, 2, 4, 1]
Есть some complex solutions, но есть ли какой-либо простые методы?
Поскольку вы добавили этот вопрос 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.])
Реальное преимущество заключается в том, что вы можете указать, как вы хотите, угловой подлежащие лечению:
>>> 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.])
Простейшее я могу думать:
rankorder = sorted(range(len(thelist)), key=thelist.__getitem__)
Это, конечно, производить [2, 1, 3, 0]
, так как индексация Python всегда с нуля - если по какой-то причине абсолютно странным вам нужно добавить один к каждому индексу вы, конечно, можете легко сделать так:
rankorder_weird = [1+x for x in rankorder]
@DSM, no I do not - Я имел в виду '__getitem__' - редактирование сейчас. –
Попробуйте однострочник:
rankorderofsomelist = [sorted(somelist).index(x) for x in somelist]
Обратите внимание, что он будет вести себя так, как ожидалось, для списка с несколькими записями того же значения (например, четыре экземпляра одного и того же значения, все из которых являются вторыми по величине в списке, будут ранжированы 2). Также обратите внимание, что сортировка по Питону возрастает (от самого маленького до самого большого) и равна нулю, поэтому вам может потребоваться последний проход по списку, чтобы увеличить ряды, отменить их и т. Д.
Вы можете включить этот проход в один лайнер. Чтобы дать нужный результат, просто используйте:
rankorderofsomelist = [len(somelist)-(sorted(somelist).index(x)) for x in somelist]
это хорошо работает. Он не обрабатывает связи, а также метод scipy, но я не указал это в вопросе. –
Это, если я не ошибаюсь, сложность N^3log (N): для каждого элемента в списке вы сортируете список, а затем выполняете линейный поиск этого элемента. Даже если вы отсортировали список раньше, а не в цикле, вы все равно будете смотреть на сложность N^2. Вы [могли бы сделать хуже] (http://c2.com/cgi/wiki?SlowSort), но вам придется очень стараться. Это страшное предложение. -1, боюсь ... – Jaime
@Jaime OP попросил простое решение, поэтому я показал ему его. Кроме того, тривиально ** уменьшить временную сложность: просто сохраните 'sorted (somelist)' в переменной выше однострочного. Это дает худшую сложность O (n^2). – Newb
Это работает невероятно хорошо, и используя этот метод из-за метода привязки связи «мин», –