7

I need a good, quick method for finding the 10 smallest real values from a numpy array that could have arbitrarily many nan and/or inf values.

I need to identify the indices of these smallest real values, not the values themselves.

I have found the argmin and nanargmin functions from numpy. They aren't really getting the job done because I also want to specify more than 1 value, like I want the smallest 100 values, for example. Also they both return -inf values as being the smallest value when it is present in the array.

heapq.nsmallest kind of works, but it also returns nan and -inf values as smallest values. Also it doesn't give me the indices that I am looking for.

Any help here would be greatly appreciated.

2
  • iterate over/copy the array, convert all nans and -inf into inf run your function to get smallest N values, convert them back/revert to the old copy? silly hacky, but hmm... Commented Apr 24, 2013 at 13:27
  • thanks for the help, that is what I will have to do if I can't get a simpler answer. Commented Apr 24, 2013 at 13:29

3 Answers 3

11

The only values that should be throwing this out are the negative infinite ones. So try:

import numpy as np
a = np.random.rand(20)
a[4] = -np.inf
k = 10
a[np.isneginf(a)] = inf
result = a[np.argsort(a)[:k]]
Sign up to request clarification or add additional context in comments.

4 Comments

2*np.max doesn't work if all elements are negative, better to just use inf I think.
The solution as it stands can be dangerous. It should be noted here that you are changing the array to make a measurement. It may be physically significant that -inf is not inf.
You can avoid modifying the original array if you want. Just sort unconditionally, then limit your results to finite values: i = np.argsort(a); result = i[np.isfinite(a[i])][:10]
@Blckknght yes that's a better solution. If you post that I'll remove my answer
2

It seems to me like you could just take the first n finite values from your sorted array, instead of trying to modify the original array, which could be dangerous.

n = 10
b = np.sort(a)
smalls = b[np.isfinite(b)][n:]

Comments

1

you can find the index of inf and Nan like this:

a=np.array([[12,12,111],[np.inf,np.inf,1,2,3],[np.nan,7,8]])

the you can loop through a and check it with:

for item in a:    
    idxInf=(np.isnan(a[item])).nonzero()
    idxNan=(np.isnan(a[item])).nonzero()

i.e:

In [17]: (np.isnan(a[2]))
Out[17]: array([ True, False, False], dtype=bool)

In [18]: (np.isnan(a[2])).nonzero()
Out[18]: (array([0]),)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.