1

I know how to find the indices of the maximum element of an n-dimensional array.

Let's have for example:

a=np.asarray([[1,7,-4],[9,-11,-17]])

Then (source):

from numpy import unravel_index
unravel_index(a.argmax(), a.shape)

returning:

(1, 0)

and indeed a[1,0] is 9, which is the highest element in the array a, so we are good.


I am also able to figure out how to find the indices of the ith largest element of a one-dimensional numpy array (using):

a = np.array([1, 3, 2, 4, 5])

i=3 # we want the third largest element, for example
a.argsort()[-i]

This returns 1, which is good, since a[1]=3 which is indeed the third largest element of a.


I would like to combine these two. So if I have

a=np.asarray([[1,7,-4],[9,-11,-17]])

I would like to get an output telling me the indices of the ith largest element of the array a, for example if i=3, the output should be [0,0], since a[0,0]=1 is the ith (third) largest element of a.

How can I do this?

zabop
  • 6,750
  • 3
  • 39
  • 84
  • https://stackoverflow.com/a/9483964/10708112 might be of some help. – hqkhan Jan 04 '19 at 22:02
  • yes, the problem is that I don't always want the maximum (ie 1st largest), but the i-th largest, which I cannot do with a.argmax(). – zabop Jan 04 '19 at 22:06

4 Answers4

3

Well to get the index of some largest or whichever, you can use where:

Adding to above answer by webDev:

import numpy as np
i=2

a=np.asarray([[1,7,-4],[9,-11,-17]])

flat=a.flatten()
flat.sort()
tryvalue= flat[-i]

i, j = np.where(a == tryvalue)
print(i,j)

This will give you:

[0] [1]

I mean you can make changes on your own that how you want these indexes to be like(tuple or whatever).

Amit Amola
  • 2,301
  • 2
  • 22
  • 37
1

This is a simple way to do so.

import numpy as np
i=3
a=np.asarray([[1,7,-4],[9,-11,-17]])
flat=a.flatten()
flat.sort()
print(flat)
print(flat[-i])
i, j = np.where(a == flat[-i])
print(i,j)

You can flatten and then sort it. It will give you the output that you want based on your ith largest i.e. i=3. If you enter i=5, flat[-i] will give you -11.

BetaDev
  • 4,516
  • 3
  • 21
  • 47
1

You can also use heapq.nlargest on the flattened array and get the minimum of those largest i elements. That should be more efficient than sorting for most cases:

import numpy as np
import heapq

a = np.asarray([[1, 7, -4], [9, -11, -17]])
i = 2

ith_largest = min(heapq.nlargest(i, a.flatten()))
x, y = np.where(a == ith_largest)
print(x, y)  # [0] [1]
slider
  • 12,810
  • 1
  • 26
  • 42
0

Amit Amola's answer is perfectly good. In case someone needs another one, I found this solution:

a=np.asarray([[1,7,-4],[9,-11,-17]])
flat=a.flatten()
flat.sort()
i=5

for k, p in enumerate(a):
    for j, q in enumerate(p):
        if q == flat[-i]:
            indices=[k,j]

print(indices)

Giving [1, 1], which is good.

zabop
  • 6,750
  • 3
  • 39
  • 84
  • 1
    Enumerate keeps a track of indices, but zabop, issue here would be of nested loop. I mean if this was working on multiple values to be found, let's say largest value to be found with their indexes of 1 lakh such arrays, that nested loop would just completely mess up the complexity. So, do take care of this issue if working on larger data. – Amit Amola Jan 04 '19 at 22:17
  • Yes, good point, this only works well for small arrays with low dimension. – zabop Jan 04 '19 at 23:46