在numpy数组中,我需要获取前N个最小值(索引)。

35

嗨,我有一个包含X个值的数组,我想找到最小的十个值的索引。在这个链接中,他们有效地计算了最大值,如何从numpy数组中获取N个最大值的索引? 然而,我还不能在链接上评论,所以我不得不重新发布问题。

我不确定需要更改哪些索引才能获得最小而不是最大值。以下是他们的代码:

In [1]: import numpy as np

In [2]: arr = np.array([1, 3, 2, 4, 5])

In [3]: arr.argsort()[-3:][::-1]
Out[3]: array([4, 3, 1]) 
5个回答

55

如果你打电话

arr.argsort()[:3]

它会给出3个最小元素的索引。

array([0, 2, 1], dtype=int64)

因此,对于n,您应该调用

arr.argsort()[:n]

30

自从发布这个问题以来,numpy已更新,包括使用argpartition从数组中选择最小元素的更快方法。它首次包含在Numpy 1.8中。

snarly的答案启发,我们可以快速找到k=3个最小的元素:

In [1]: import numpy as np

In [2]: arr = np.array([1, 3, 2, 4, 5])

In [3]: k = 3

In [4]: ind = np.argpartition(arr, k)[:k]

In [5]: ind
Out[5]: array([0, 2, 1])

In [6]: arr[ind]
Out[6]: array([1, 2, 3])

由于不需要完全排序,因此此代码将在O(n)时间内运行。如果您需要对答案进行排序(注意:在本例中输出数组已按排序顺序排列,但不能保证),则可以对输出进行排序:

In [7]: sorted(arr[ind])
Out[7]: array([1, 2, 3])

这个算法的时间复杂度为O(n + k log k),因为排序是在较小的输出列表上进行的。


8

我不能保证这样做会更快,但一个更好的算法将依赖于heapq

import heapq
indices = heapq.nsmallest(10,np.nditer(arr),key=arr.__getitem__)

这应该可以在大约O(N)的操作中完成,而使用argsort需要O(NlogN)的操作。但是,后者被推入高度优化的C语言中,所以它可能仍然表现更好。要确定,您需要在实际数据上运行一些测试。

哦,好的,这也可以。我之前尝试使用过它,但有些东西我没明白,变得有点复杂,不过现在它能用了,谢谢 :] - astrochris
我也试过了,对我来说也可以。但是在我的情况下,它比纯numpy解决方案慢大约20倍。 - embert

3

不要反转排序结果。

In [164]: a = numpy.random.random(20)

In [165]: a
Out[165]: 
array([ 0.63261763,  0.01718228,  0.42679479,  0.04449562,  0.19160089,
        0.29653725,  0.93946388,  0.39915215,  0.56751034,  0.33210873,
        0.17521395,  0.49573607,  0.84587652,  0.73638224,  0.36303797,
        0.2150837 ,  0.51665416,  0.47111993,  0.79984964,  0.89231776])

已排序:

In [166]: a.argsort()
Out[166]: 
array([ 1,  3, 10,  4, 15,  5,  9, 14,  7,  2, 17, 11, 16,  8,  0, 13, 18,
       12, 19,  6])

前十个:

In [168]: a.argsort()[:10]
Out[168]: array([ 1,  3, 10,  4, 15,  5,  9, 14,  7,  2])

2
这段代码将split_list中最大的20个元素的索引保存在Twenty_Maximum中:
Twenty_Maximum = split_list.argsort()[-20:]

针对这段代码,在split_list中找到最小元素的下标,并将前20个最小元素的下标存储在Twenty_Minimum中:

Twenty_Minimum = split_list.argsort()[:20]

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