如果这是一个重复的问题,我很抱歉,我查找了这些信息,但仍然无法找到它。
是否可以通过非常有效地使用递减顺序的N个最大元素的索引来排列numpy数组(或python列表)?
例如,数组:
a = array([4, 1, 0, 8, 5, 2])
按降序排列的最大元素的索引将给出(考虑N = 6,包括所有元素):
8 - > 3
5 - > 4
4 - > 0
2 - > 5
1 - > 1
0 - > 2
result = [3, 4, 0, 5, 1, 2]
我知道如何使用一种有点愚蠢的方法(比如对数组进行排序并搜索其索引中每个N个数字),但我想知道是否有任何有效的库,如瓶颈或heapq或者pythonic这种方法非常快。我必须在几个阵列中应用它,每个阵列有300k元素,这就是性能问题的原因。
提前致谢!
更新
我读了答案并决定使用300k的随机整数来计算它们,结果如下:
解决方案1: sorted(range(len(a)), key=lambda i:a[i])
时间: 230毫秒
解决方案2: heapq.nlargest(len(a), zip(a, itertools.count()))
时间:396 ms
解决方案3: heapq.nlargest(len(a), enumerate(a), key=operator.itemgetter(1))
时间: 864 ms
解决方案4: def f(a,N): return np.argsort(a)[::-1][:N] (N = len(a))
时间:104毫秒
非常感谢快速而又非常好的答案!
答案 0 :(得分:19)
您是否看过内置的numpy argsort
方法?:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.argsort.html
我可以使用该方法在我的机器上在大约29毫秒内对300,000随机浮点数组合排序。
def f(a,N):
return np.argsort(a)[::-1][:N]
答案 1 :(得分:11)
L = [4, 1, 0, 8, 5, 2]
sorted(range(len(L)), key=lambda i:L[i])
答案 2 :(得分:5)
您可以使用heapq
轻松完成此操作:
>>> heapq.nlargest(3, zip(a, itertools.count()))
[(8, 3), (5, 4), (4, 5)]
通过对第一个值进行排序来排序元组,然后对第二个值进行排序等等...这意味着我们可以简单地创建一个(value, index)
元组并进行排序,为我们提供值的索引(值为也给了,但我们可以很容易地扔掉它们。)
我使用zip()
和itertools.count()
作为枚举为我们提供了错误的顺序,因此它们将按索引排序,而不是按值排序。或者,您也可以((value, index) for index, value in enumerate(a))
,但我觉得不太清楚。
另一种方法是提供密钥,执行heapq.nlargest(3, enumerate(a), key=operator.itemgetter(1))
。
答案 3 :(得分:0)
使用heapq的另一种方法
heapq.nlargest(n, range(len(a)), key=a.__getitem__)
正如其他地方所评论的那样,除非a非常大并且n<<len(a)
,否则它不会超过排序,因为排序在Python中是一个相对较快的操作。然而,最终慢速O(n)总是会超过O(n * log(n))