Python 从numpy数组中获取最大或最小n元素?(最好不要压扁)

Python 从numpy数组中获取最大或最小n元素?(最好不要压扁),python,arrays,numpy,max,slice,Python,Arrays,Numpy,Max,Slice,我知道我可以通过以下方式获得最小值或最大值: max(matrix) min(matrix) 从一个numpy矩阵/向量中。这些价值的指数通过以下方式返回: argmax(matrix) argmin(matrix) 例如,当我有一个5x5矩阵时: a = np.arange(5*5).reshape(5, 5) + 10 # array([[10, 11, 12, 13, 14], # [15, 16, 17, 18, 19], # [20, 21, 22,

我知道我可以通过以下方式获得最小值或最大值:

max(matrix)
min(matrix)
从一个numpy矩阵/向量中。这些价值的指数通过以下方式返回:

argmax(matrix)
argmin(matrix)
例如,当我有一个5x5矩阵时:

a = np.arange(5*5).reshape(5, 5) + 10

# array([[10, 11, 12, 13, 14],
#        [15, 16, 17, 18, 19],
#        [20, 21, 22, 23, 24],
#        [25, 26, 27, 28, 29],
#        [30, 31, 32, 33, 34]])
我可以通过以下方式获得最大值:

In [86]: np.max(a) # getting the max-value out of a
Out[86]: 34

In [87]: np.argmax(a) # index of max-value 34 is 24 if array a were flattened
Out[87]: 24
…但获得最大或最小n元素的最有效方法是什么

让我们说,从a中,我想要5个最高元素和5个最低元素。这应该会返回我
[30,31,32,33,34]
,分别获取5个最高值
[20,21,22,23,24]
,获取它们的索引。同样地,
[10,11,12,13,14]
用于5个最低值,而
[0,1,2,3,4]
用于5个最低元素的索引

对于这一点,什么是有效、合理的解决方案

我的第一个想法是对数组进行展平和排序,并取最后和前5个值。然后,我在原始2D矩阵中搜索这些值的索引虽然此过程有效,但展平+排序不是很有效……有人知道更快的解决方案吗?


此外,我想有原始二维数组的索引,而不是平坦的一个。因此,我不想使用
np.argmax(a)
返回
24
,而是希望使用
(4,4)

获取数组中最大或最小值的索引的标准方法是使用。此函数使用introselect算法并以线性复杂度运行-这比对较大数组(通常为O(n logn))进行完全排序要好

默认情况下,此函数沿阵列的最后一个轴工作。要考虑整个数组,需要使用。例如,这里有一个随机数组
a

>>> a = np.random.randint(0, 100, size=(5, 5))
>>> a
array([[60, 68, 86, 66,  9],
       [66, 26, 83, 87, 50],
       [41, 26,  0, 55,  9],
       [57, 80, 71, 50, 22],
       [94, 30, 95, 99, 76]])
然后,要获取(展平)2D数组中五个最大值的索引,请使用:

>>> i = np.argpartition(a.ravel(), -5)[-5:] # argpartition(a.ravel(), 5)[:5] for smallest
>>> i
array([ 2,  8, 22, 23, 20])
要返回
a
中这些位置的相应2D索引,请使用:

然后用
i2d
索引
a
,返回五个最大值:

>>> a[i2d]
array([86, 87, 95, 99, 94])

np.partition
(索引的
np.argpartition
)是O(n)-我认为这是您在这里所能期望的最好结果。它需要首先对数组进行散开(这应该只创建一个视图,因此不会导致任何性能损失)。然后,您可以使用
unravel_index
获取原始数组中的二维索引。在这种情况下,排序速度更快:
%timeit a.ravel.argpartition(-5)->5.5µs
%timeit a.ravel.argsort()->3.8µs
。当然,对于更大的阵列,这是正确的方法。
>>> a[i2d]
array([86, 87, 95, 99, 94])