I have need the N minimum (index) values in a numpy array

55,736

Solution 1

If you call

arr.argsort()[:3]

It will give you the indices of the 3 smallest elements.

array([0, 2, 1], dtype=int64)

So, for n, you should call

arr.argsort()[:n]

Solution 2

Since this question was posted, numpy has updated to include a faster way of selecting the smallest elements from an array using argpartition. It was first included in Numpy 1.8.

Using snarly's answer as inspiration, we can quickly find the k=3 smallest elements:

In [1]: import numpy as np

In [2]: arr = np.array([1, 3, 2, 4, 5])

In [3]: k = 3

In [4]: ind = np.argpartition(arr, k)[:k]

In [5]: ind
Out[5]: array([0, 2, 1])

In [6]: arr[ind]
Out[6]: array([1, 2, 3])

This will run in O(n) time because it does not need to do a full sort. If you need your answers sorted (Note: in this case the output array was in sorted order but that is not guaranteed) you can sort the output:

In [7]: sorted(arr[ind])
Out[7]: array([1, 2, 3])

This runs on O(n + k log k) because the sorting takes place on the smaller output list.

Solution 3

I don't guarantee that this will be faster, but a better algorithm would rely on heapq.

import heapq
indices = heapq.nsmallest(10,np.nditer(arr),key=arr.__getitem__)

This should work in approximately O(N) operations whereas using argsort would take O(NlogN) operations. However, the other is pushed into highly optimized C, so it might still perform better. To know for sure, you'd need to run some tests on your actual data.

Solution 4

Just don't reverse the sort results.

In [164]: a = numpy.random.random(20)

In [165]: a
Out[165]: 
array([ 0.63261763,  0.01718228,  0.42679479,  0.04449562,  0.19160089,
        0.29653725,  0.93946388,  0.39915215,  0.56751034,  0.33210873,
        0.17521395,  0.49573607,  0.84587652,  0.73638224,  0.36303797,
        0.2150837 ,  0.51665416,  0.47111993,  0.79984964,  0.89231776])

Sorted:

In [166]: a.argsort()
Out[166]: 
array([ 1,  3, 10,  4, 15,  5,  9, 14,  7,  2, 17, 11, 16,  8,  0, 13, 18,
       12, 19,  6])

First ten:

In [168]: a.argsort()[:10]
Out[168]: array([ 1,  3, 10,  4, 15,  5,  9, 14,  7,  2])

Solution 5

This code save 20 index of maximum element of split_list in Twenty_Maximum:

Twenty_Maximum = split_list.argsort()[-20:]

against this code save 20 index of minimum element of split_list in Twenty_Minimum:

Twenty_Minimum = split_list.argsort()[:20]
Share:
55,736
astrochris
Author by

astrochris

Astrophysicist trying to use python, and slowly getting there, very slowly. My main work is with image .fits files and star catalogs.

Updated on November 12, 2020

Comments

  • astrochris
    astrochris over 3 years

    Hi I have an array with X amount of values in it I would like to locate the indexs of the ten smallest values. In this link they calculated the maximum effectively, How to get indices of N maximum values in a numpy array? however I cant comment on links yet so I'm having to repost the question.

    I'm not sure which indices i need to change to achieve the minimum and not the maximum values. This is their code

    In [1]: import numpy as np
    
    In [2]: arr = np.array([1, 3, 2, 4, 5])
    
    In [3]: arr.argsort()[-3:][::-1]
    Out[3]: array([4, 3, 1]) 
    
  • astrochris
    astrochris almost 11 years
    o yeah, this works as well. I tried to use it before but was missing some of it and it got a bit complicated, but it works now thanks :]
  • embert
    embert over 10 years
    Works for me as well. However, in my case it is about 20 times slower than the pure numpy solution