Numpy: 在ndarray的每一行中找到第二高的值的索引

6

我有一个[10,10]numpy.ndarray。我想要找到每一行第二大的数的索引。对于以下数组:

[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]

期望结果:[8, 2, 8, 5, 9, ...]

有任何建议吗?


请问您能否更新一下问题,展示一下您已经尝试或者研究过的内容?您目前遇到了什么困难呢? - S3DEV
3个回答

14
惊人的numpy.argsort()函数使得这个任务变得非常简单。一旦找到了排序后的索引,就可以获取倒数第二列。

使用 numpy.argsort() 函数,这个任务变得十分简单。一旦找到排好序的索引,获取倒数第二列即可。

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)

1

我对一些事情感到困惑,比如:

1 - 如果最高的数字重复了,你会把它视为第二高的数字吗?

2 - 如果第二高的数字重复了,你想知道数组中所有出现的位置还是只有第一次出现的位置?

无论如何,这是我对我的解释的解决方案:

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

1

使用argpartition可能比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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接