如何在Python中选择`numpy.ndarray`的前三个最大值?

3 投票
3 回答
3915 浏览
提问于 2025-04-16 19:03

我有一个存储了浮点数(包括正数和负数)的列表,这个列表保存在一个叫 row 的变量里,类型是 <type 'numpy.ndarray'>

max_value = max(row)

这个方法可以让我找到 row 中的最大值。有没有什么简单的方法可以选出前 3 个(或者 5 个、10 个)值呢?

我想到了以下步骤:

  1. row 中选择最大值
  2. 把这个最大值从 row 中删除
  3. 再从 row 中选择最大值
  4. 再把这个最大值删除
  5. 依此类推

不过这样做显得很笨拙,也不符合 Python 的风格。Python 的高手们对此有什么看法呢? :)


编辑

我不仅需要最大的三个值,还需要它们在 row 中的位置(索引)。抱歉,我忘了提这点……

3 个回答

1

这个看起来不太好看的方法在我的老款Mac PPC上,使用numpy 1.5.1时,比argsort()[-3:]要快一些。
Bottleneck库中的argpartsort,还有一些用Cython写的NumPy数组函数,会快得多。

#!/bin/sh

python -mtimeit -s '
import numpy as np

def max3( A ):
   j = A.argmax();  aj = A[j];  A[j] = - np.inf
   j2 = A.argmax();  aj2 = A[j2];  A[j2] = - np.inf
   j3 = A.argmax()
   A[j] = aj
   A[j2] = aj2
   return [j, j2, j3]

N = '${N-1e6}'
A = np.arange(N)
' '
j3 = A.argsort()[-3:]   # N 1e6: 405 msec per loop
# j3 = max3( A )        # N 1e6: 105 msec per loop
'
2

为什么不直接对numpy数组进行排序,然后读取你需要的值呢:

In [33]: np.sort(np.array([1,5,4,6,7,2,3,9]))[-3:]
Out[33]: array([6, 7, 9])

补充说明:因为问题现在变了,你不仅需要值,还需要它们的位置,可以使用 numpy.argsort 来获取索引,而不是值:

In [43]: a=np.array([1,5,4,6,7,2,3,9])

In [44]: idx=np.argsort(a)

In [45]: topvals=idx[-3:]

In [46]: print topvals
[3 4 7]

In [47]: print a[topvals]
[6 7 9]
9

我会使用 np.argsort

a = np.arange(10)
a[np.argsort(a)[-3:]]

编辑:如果你还想得到位置,可以直接使用:

ii = np.argsort(a)[-3:] # positions
vals = a[ii]            # values

撰写回答