Dr.PB
Dr.PB

Reputation: 1067

Find index of max element in numpy array excluding few indexes

Say:

p = array([4, 0, 8, 2, 7])

Want to find the index of max value, except few indexes, say:

excptIndx = [2, 3]

Ans: 4, as 7 will be max.

if excptIndx = [1, 3], Ans: 2, as 8 will be max.

Upvotes: 5

Views: 3001

Answers (4)

Dr.PB
Dr.PB

Reputation: 1067

p = np.array([4,0,8,2,7])   # given
exceptions = [2,3]   # given

idx = list( range(0,len(p)) )   # simple array of index
a1 = np.delete(idx, exceptions)   # remove exceptions from idx (i.e., index)
a2 = np.argmax(np.delete(p, exceptions))   # get index of the max value after removing exceptions from actual p array

a1[a2]   # as a1 and a2 are in sync, this will give the original index (as asked) of the max value

Upvotes: 0

Austin
Austin

Reputation: 26039

In numpy, you can mask all values at excptIndx and run argmax to obtain index of max element:

import numpy as np

p = np.array([4, 0, 8, 2, 7])
excptIndx = [2, 3]

m = np.zeros(p.size, dtype=bool)
m[excptIndx] = True
a = np.ma.array(p, mask=m)
print(np.argmax(a))
# 4

Upvotes: 6

hpaulj
hpaulj

Reputation: 231385

The setup:

In [153]: p = np.array([4,0,8,2,7])                                                              
In [154]: exceptions = [2,3]                                                                     

Original indexes in p:

In [155]: idx = np.arange(p.shape[0])                                                            

delete exceptions from both:

In [156]: np.delete(p,exceptions)                                                                
Out[156]: array([4, 0, 7])
In [157]: np.delete(idx,exceptions)                                                              
Out[157]: array([0, 1, 4])

Find the argmax in the deleted array:

In [158]: np.argmax(np.delete(p,exceptions))                                                     
Out[158]: 2

Use that to find the max value (could just as well use np.max(_156)

In [159]: _156[_158]                                                                             
Out[159]: 7

Use the same index to find the index in the original p

In [160]: _157[_158]                                                                             
Out[160]: 4
In [161]: p[_160]    # another way to get the max value                                                                            
Out[161]: 7

For this small example, the pure Python alternatives might well be faster. They often are in small cases. We need test cases with a 1000 or more values to really see the advantages of numpy.

Another method

Set the exceptions to a small enough value, and take the argmax:

In [162]: p1 = p.copy(); p1[exceptions] = -1000                                                  
In [163]: np.argmax(p1)                                                                          
Out[163]: 4

Here the small enough is easy to pick; more generally it may require some thought.

Or taking advantage of the np.nan... functions:

In [164]: p1 = p.astype(float); p1[exceptions]=np.nan                                            
In [165]: np.nanargmax(p1) 
Out[165]: 4

Upvotes: 2

bluewhale
bluewhale

Reputation: 307

A solution is

mask = np.isin(np.arange(len(p)), excptIndx)
subset_idx = np.argmax(p[mask])
parent_idx = np.arange(len(p))[mask][subset_idx]

See http://seanlaw.github.io/2015/09/10/numpy-argmin-with-a-condition/

Upvotes: 1

Related Questions