我需要一个 numpy 数组中的 N 个最小(索引)值
Posted
技术标签:
【中文标题】我需要一个 numpy 数组中的 N 个最小(索引)值【英文标题】:I have need the N minimum (index) values in a numpy array 【发布时间】:2013-05-24 22:52:23 【问题描述】:嗨,我有一个包含 X 个值的数组,我想找到十个最小值的索引。在这个链接中,他们有效地计算了最大值,How to get indices of N maximum values in a numpy array? 但是我还不能对链接发表评论,所以我不得不重新发布这个问题。
我不确定需要更改哪些指标才能达到最小值而不是最大值。 这是他们的代码
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])
【问题讨论】:
【参考方案1】:如果你打电话
arr.argsort()[:3]
它将为您提供 3 个最小元素的索引。
array([0, 2, 1], dtype=int64)
所以,对于n
,你应该调用
arr.argsort()[:n]
【讨论】:
【参考方案2】:我不保证这会更快,但更好的算法将依赖于heapq
。
import heapq
indices = heapq.nsmallest(10,np.nditer(arr),key=arr.__getitem__)
这应该在大约O(N)
操作中起作用,而使用argsort
将需要O(NlogN)
操作。然而,另一个被推到高度优化的 C 中,所以它可能仍然表现得更好。要确定,您需要对实际数据进行一些测试。
【讨论】:
o 是的,这也有效。我之前尝试过使用它,但遗漏了一些,它有点复杂,但现在可以使用了,谢谢:] 也适合我。但是,就我而言,它比纯 numpy 解决方案慢了大约 20 倍【参考方案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])
【讨论】:
【参考方案4】:自发布此问题以来,numpy 已更新为包含使用argpartition
从数组中选择最小元素的更快方法。它首先包含在 Numpy 1.8 中。
以snarly's answer为灵感,我们可以快速找到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) 上运行,因为排序发生在较小的 输出列表。
【讨论】:
【参考方案5】:这段代码在Twenty_Maximum
中保存split_list
的最大元素的20个索引:
Twenty_Maximum = split_list.argsort()[-20:]
针对此代码,在Twenty_Minimum
中保存split_list
的最小元素的20 个索引:
Twenty_Minimum = split_list.argsort()[:20]
【讨论】:
以上是关于我需要一个 numpy 数组中的 N 个最小(索引)值的主要内容,如果未能解决你的问题,请参考以下文章
使用 NumPy 从矩阵中获取最小/最大 n 值和索引的有效方法
Python | 快速获取某一列数组中前 N 个最大值/最小值的索引 | 三种方法总结