简体   繁体   English

numpy:返回一个数组,其中n个条目最接近给定数字

[英]Numpy: give back an array with the n entries closest to a given number

I have a numpy array arr and I want to create a new array with the n elements of the old one, that are the closest to a given number x . 我有一个numpy数组arr ,我想用旧元素的n元素创建一个新数组,这些元素最接近给定数x I've found a helpful answer here ( I have need the N minimum (index) values in a numpy array ), but my code seems very clumsy (I'm a beginner in Python): 我在这里找到了一个有用的答案( 我需要一个numpy数组中的N个最小值(索引)值 ),但是我的代码似乎很笨拙(我是Python的初学者):

def give_array_with_closest(x, n, arr):
    newar = np.absolute(arr - (np.ones(len(arr)) * x)) #Subtract x from all array entries and take absolute value, so that the lowest entries are the ones closest to x
    indexar = (newar).argsort()[:n] #get array with indices from n lowest entries of newar
    result = np.empty(n)
    for i in range(n):
        result[i] = arr[indexar[i]]
    return result

Since I'm not interested in the indices but only the actual entries, maybe the solution of the other question isn't the best in this case. 由于我对索引不感兴趣,而对实际条目不感兴趣,因此在这种情况下,另一个问题的解决方案可能不是最好的。 Is there a more efficient and simpler way to do this? 有没有更有效,更简单的方法来做到这一点?

  • It has been mentioned already that you don't need the for-loop to get the values for the indices, you can simply use the result of argsort to index the array (at least if your arrays are 1D). 已经提到,您不需要for循环即可获取索引的值,只需使用argsort的结果argsort为数组建立索引(至少在数组为1D的情况下)。

  • But you also don't need to sort the full array. 但是您也不需要sort整个数组进行sort You could simply use argpartition . 您可以简单地使用argpartition That could be faster than sorting. 可能比排序更快。

  • As additional point: You can use vectorized operations like arr - 1 . 另外,您可以使用矢量化操作,例如arr - 1 That will subtract one from each element without needing to create a new array manually (like your np.ones(len(arr)) ). 这将从每个元素中减去一个,而无需手动创建新的数组(例如np.ones(len(arr)) )。

So putting these together: 因此,将它们放在一起:

def give_array_with_closest(x, n, arr):
    indexarr = np.argpartition(abs(arr - x), n)[:n]
    return arr[indexarr]

And the test: 和测试:

>>> give_array_with_closest(2, 3, np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
array([2, 3, 1])

You could create new array one-call by providing indices: 您可以通过提供索引来创建新的数组一次调用:

def give_array_with_closest2(x, n, arr):
    newar = np.absolute(arr - (np.ones(len(arr)) * x)) 
    return arr[(newar).argsort()[:n]] 

So actually this is the same code, but more elegant and probably faster. 因此,实际上这是相同的代码,但是更优雅,而且可能更快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM