2015-03-02 3 views

ответ

3

Поскольку вы добавили этот вопрос 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.]) 
+0

Это работает невероятно хорошо, и используя этот метод из-за метода привязки связи «мин», –

4

Простейшее я могу думать:

rankorder = sorted(range(len(thelist)), key=thelist.__getitem__) 

Это, конечно, производить [2, 1, 3, 0], так как индексация Python всегда с нуля - если по какой-то причине абсолютно странным вам нужно добавить один к каждому индексу вы, конечно, можете легко сделать так:

rankorder_weird = [1+x for x in rankorder] 
+0

@DSM, no I do not - Я имел в виду '__getitem__' - редактирование сейчас. –

2

Попробуйте однострочник:

rankorderofsomelist = [sorted(somelist).index(x) for x in somelist] 

Обратите внимание, что он будет вести себя так, как ожидалось, для списка с несколькими записями того же значения (например, четыре экземпляра одного и того же значения, все из которых являются вторыми по величине в списке, будут ранжированы 2). Также обратите внимание, что сортировка по Питону возрастает (от самого маленького до самого большого) и равна нулю, поэтому вам может потребоваться последний проход по списку, чтобы увеличить ряды, отменить их и т. Д.

Вы можете включить этот проход в один лайнер. Чтобы дать нужный результат, просто используйте:

rankorderofsomelist = [len(somelist)-(sorted(somelist).index(x)) for x in somelist] 
+0

это хорошо работает. Он не обрабатывает связи, а также метод scipy, но я не указал это в вопросе. –

+1

Это, если я не ошибаюсь, сложность N^3log (N): для каждого элемента в списке вы сортируете список, а затем выполняете линейный поиск этого элемента. Даже если вы отсортировали список раньше, а не в цикле, вы все равно будете смотреть на сложность N^2. Вы [могли бы сделать хуже] (http://c2.com/cgi/wiki?SlowSort), но вам придется очень стараться. Это страшное предложение. -1, боюсь ... – Jaime

+0

@Jaime OP попросил простое решение, поэтому я показал ему его. Кроме того, тривиально ** уменьшить временную сложность: просто сохраните 'sorted (somelist)' в переменной выше однострочного. Это дает худшую сложность O (n^2). – Newb

Смежные вопросы