How to select not only the maximum of `numpy.ndarray`, but also the top 3 maximum values ​​in python?

I have a list of float values ​​(positive and negative) stored in a rowtype variable <type 'numpy.ndarray'>.

max_value = max(row)

gives the maximum value row. Is there an elegant way to select the top 3 (5, 10, ...) values?

I figured it out

  • select maximum value row
  • removing the maximum value in row
  • select maximum value row
  • removing the maximum value in row
  • etc.

But this is definitely an ugly style, not a pythonic one at all. What do pionists say about this? :)


Edit

I need not only the maximum three values, but also the position (index at row). Sorry, I forgot to mention this ...

+3
source share
3 answers

I would use np.argsort

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

, :

ii = np.argsort(a)[-3:] # positions
vals = a[ii]            # values
+9

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]
+1

This ugly trick is somewhat faster than argsort()[-3:]at least in numpy 1.5.1 on my old mac ppc.
argpartsort in Bottleneck , some functions of the NumPy array written in Cython will be faster.

#!/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
source

All Articles