Python 在numpy数组中找到第n个最小元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22546180/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 01:08:12  来源:igfitidea点击:

Find nth smallest element in numpy array

pythonnumpy

提问by Akavall

I need to find just the the smallest nth element in a 1D numpy.array.

我只需要找到 1D 中最小的第 n 个元素numpy.array

For example:

例如:

a = np.array([90,10,30,40,80,70,20,50,60,0])

I want to get 5th smallest element, so my desired output is 40.

我想获得第 5 个最小的元素,所以我想要的输出是40.

My current solution is this:

我目前的解决方案是这样的:

result = np.max(np.partition(a, 5)[:5])

However, finding 5 smallest elements and then taking the largest one them seems little clumsy to me. Is there a better way to do it? Am I missing a single function that would achieve my goal?

然而,找到 5 个最小的元素然后取最大的一个对我来说似乎并不笨拙。有没有更好的方法来做到这一点?我是否缺少一个可以实现我的目标的功能?

There are questions with similar titles to this one, but I did not see anything that answered my question.

有一些与此问题标题相似的问题,但我没有看到任何可以回答我的问题的问题。

Edit:

编辑:

I should've mentioned it originally, but performance is very important for me; therefore, heapqsolution though nice would not work for me.

我本来应该提到它的,但性能对我来说非常重要;因此,heapq虽然很好的解决方案对我不起作用。

import numpy as np
import heapq

def find_nth_smallest_old_way(a, n):
    return np.max(np.partition(a, n)[:n])

# Solution suggested by Jaime and HYRY    
def find_nth_smallest_proper_way(a, n):
    return np.partition(a, n-1)[n-1]

def find_nth_smallest_heapq(a, n):
    return heapq.nsmallest(n, a)[-1]
#    
n_iterations = 10000

a = np.arange(1000)
np.random.shuffle(a)

t1 = timeit('find_nth_smallest_old_way(a, 100)', 'from __main__ import find_nth_smallest_old_way, a', number = n_iterations)
print 'time taken using partition old_way: {}'.format(t1)    
t2 = timeit('find_nth_smallest_proper_way(a, 100)', 'from __main__ import find_nth_smallest_proper_way, a', number = n_iterations)
print 'time taken using partition proper way: {}'.format(t2) 
t3 = timeit('find_nth_smallest_heapq(a, 100)', 'from __main__ import find_nth_smallest_heapq, a', number = n_iterations)  
print 'time taken using heapq : {}'.format(t3)

Result:

结果:

time taken using partition old_way: 0.255564928055
time taken using partition proper way: 0.129678010941
time taken using heapq : 7.81094002724

采纳答案by Jaime

Unless I am missing something, what you want to do is:

除非我遗漏了什么,否则你想做的是:

>>> a = np.array([90,10,30,40,80,70,20,50,60,0])
>>> np.partition(a, 4)[4]
40

np.partition(a, k)will place the k-th smallest element of aat a[k], smaller values in a[:k]and larger values in a[k+1:]. The only thing to be aware of is that, because of the 0 indexing, the fifth element is at index 4.

np.partition(a, k)将放置at的k第 -th 个最小元素,将较小的值放入,将较大的值放入。唯一需要注意的是,由于 0 索引,第五个元素位于索引 4。aa[k]a[:k]a[k+1:]

回答by arshajii

You can use heapq.nsmallest:

您可以使用heapq.nsmallest

>>> import numpy as np
>>> import heapq
>>> 
>>> a = np.array([90,10,30,40,80,70,20,50,60,0])
>>> heapq.nsmallest(5, a)[-1]
40

回答by HYRY

you don't need call numpy.max():

你不需要打电话numpy.max()

def nsmall(a, n):
    return np.partition(a, n)[n]