Как выбрать не только максимум `numpy.ndarray`, но и верхние 3 максимальных значения в python? - PullRequest
3 голосов
/ 06 июня 2011

У меня есть список значений с плавающей запятой (положительных и отрицательных), хранящихся в переменной row типа <type 'numpy.ndarray'>.

max_value = max(row)

дает мне максимальное значение row. Есть ли элегантный способ выбрать 3 верхних (5, 10, ...) значения?

Я придумал

* * 1010 выбор максимального значения из row удаление максимального значения в row выбор максимального значения из row удаление максимального значения в row и т. Д.

Но это, безусловно, уродливый стиль и вовсе не питонический. Что на это говорят питонисты? :)


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

Мне нужны не только три максимальных значения, битовая позиция (индекс в row), тоже. Извините, я забыл упомянуть, что ...

Ответы [ 3 ]

9 голосов
/ 06 июня 2011

Я бы использовал np.argsort

a = np.arange(10)
a[np.argsort(a)[-3:]]

РЕДАКТИРОВАТЬ Чтобы также получить позицию, просто используйте:

ii = np.argsort(a)[-3:] # positions
vals = a[ii]            # values
1 голос
/ 14 июня 2011

Этот уродливый трюк несколько быстрее, чем argsort()[-3:], по крайней мере в numpy 1.5.1 на моем старом компьютере Mac.
argpartsort in Узкое место , некоторые функции массива NumPy, написанные на Cython, будут более быстрыми.

#!/bin/sh

python -mtimeit -s '
import numpy as np

def max3( A ):
   j = A.argmax();  aj = A[j];  A[j] = - np.inf
   j2 = A.argmax();  aj2 = A[j2];  A[j2] = - np.inf
   j3 = A.argmax()
   A[j] = aj
   A[j2] = aj2
   return [j, j2, j3]

N = '${N-1e6}'
A = np.arange(N)
' '
j3 = A.argsort()[-3:]   # N 1e6: 405 msec per loop
# j3 = max3( A )        # N 1e6: 105 msec per loop
'
1 голос
/ 06 июня 2011

Почему бы просто не отсортировать массив numpy, а затем прочитать нужные значения:

In [33]: np.sort(np.array([1,5,4,6,7,2,3,9]))[-3:]
Out[33]: array([6, 7, 9])

РЕДАКТИРОВАТЬ: видя, как вопрос теперь изменился, и вам нужны позиции и значения, используйте numpy.argsort, чтобы получить индексы вместо значений:

In [43]: a=np.array([1,5,4,6,7,2,3,9])

In [44]: idx=np.argsort(a)

In [45]: topvals=idx[-3:]

In [46]: print topvals
[3 4 7]

In [47]: print a[topvals]
[6 7 9]
...