4

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.

sshashank124
  • 31,495
  • 9
  • 67
  • 76
Dr.PB
  • 959
  • 1
  • 13
  • 34
  • Don't want to mark as duplicate but this is relevant: [How to select inverse of indexes of a numpy array?](https://stackoverflow.com/questions/25330959/how-to-select-inverse-of-indexes-of-a-numpy-array) – sshashank124 Jan 15 '20 at 05:43

4 Answers4

6

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
Austin
  • 25,759
  • 4
  • 25
  • 48
2

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
hpaulj
  • 221,503
  • 14
  • 230
  • 353
1

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/

bluewhale
  • 167
  • 3
  • 13
0
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
Dr.PB
  • 959
  • 1
  • 13
  • 34
  • 2
    While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value – byaruhaf Jan 15 '20 at 12:05