Reputation: 139
I have a [10,10]
numpy.ndarray
. I am trying to get the index the second highest number in each row. So for the array:
[101 0 1 0 0 0 1 1 2 0]
[ 0 116 1 0 0 0 0 0 1 0]
[ 1 4 84 2 2 0 2 4 6 1]
[ 0 2 0 84 0 6 0 2 3 0]
[ 0 0 1 0 78 0 0 2 0 11]
[ 2 0 0 1 1 77 5 0 2 0]
[ 1 2 1 0 1 2 94 0 1 0]
[ 0 1 1 0 0 0 0 96 0 4]
[ 1 5 4 3 1 3 0 1 72 4]
[ 0 1 0 0 3 2 0 7 0 82]
Expected result: [8, 2, 8, 5, 9, ...]
Any suggestions?
Upvotes: 7
Views: 9923
Reputation: 25239
Use argpartition
may be faster than argsort
In [167]: n = 2
In [168]: arr.argpartition(-n)[:,-n]
Out[168]: array([8, 8, 8, 5, 9, 6, 1, 9, 1, 7], dtype=int32)
Upvotes: 2
Reputation: 9681
The amazing numpy.argsort()
function makes this task really simple. Once the sorted indices are found, get the second to last column.
m = np.array([[101, 0, 1, 0, 0, 0, 1, 1, 2, 0],
[ 0, 116, 1, 0, 0, 0, 0, 0, 1, 0],
[ 1, 4, 84, 2, 2, 0, 2, 4, 6, 1],
[ 0, 2, 0, 84, 0, 6, 0, 2, 3, 0],
[ 0, 0, 1, 0, 78, 0, 0, 2, 0, 11],
[ 2, 0, 0, 1, 1, 77, 5, 0, 2, 0],
[ 1, 2, 1, 0, 1, 2, 94, 0, 1, 0],
[ 0, 1, 1, 0, 0, 0, 0, 96, 0, 4],
[ 1, 5, 4, 3, 1, 3, 0, 1, 72, 4],
[ 0, 1, 0, 0, 3, 2, 0, 7, 0, 82]])
# Get index for the second highest value.
m.argsort()[:,-2]
array([8, 8, 8, 5, 9, 6, 5, 9, 1, 7], dtype=int32)
Upvotes: 15
Reputation: 19
I got confused about some things, like:
1 - If the highest number repeats, would you consider it as the second highest number?
2 - If the second highest number repeats, would you like to know all its positions in the array or just the first appearance?
Anyway, there is my solution for my interpretation:
import numpy as np
my_array = np.array([[101 ,0 ,1 ,0 ,0 ,0 ,1 ,1 ,2 ,0],
[ 0 ,116 ,1 ,0 ,0 ,0 ,0 ,0 ,1 ,0],
[ 1 ,4 ,84 ,2 ,2 ,0 ,2 ,4 ,6 ,1],
[ 0 ,2 ,0 ,84 ,0 ,6 ,0 ,2 ,3 ,0],
[ 0 ,0 ,1 ,0 ,78 ,0 ,0 ,2 ,0 ,11],
[ 2 ,0 ,0 ,1 ,1 ,77 ,5 ,0 ,2 ,0],
[ 1 ,2 ,1 ,0 ,1 ,2 ,94 ,0 ,1 ,0],
[ 0 ,1 ,1 ,0 ,0 ,0 ,0 ,96 ,0 ,4],
[ 1 ,5 ,4 ,3 ,1 ,3 ,0 ,1 ,72 ,4],
[ 0 ,1 ,0 ,0 ,3 ,2 ,0 ,7 ,0 ,82]])
result = []
for row in my_array:
second = np.sort(row)[-2] #Finds the second highest number
i = np.where(row == second) #Looks for where the condition is true
result.append(i[0][0]) #Appends the first occurence
Upvotes: 1