Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在实数数组中查找最近元素的最快方法_Python_Search_Tree_Binary Search Tree_Kdtree - Fatal编程技术网

Python 在实数数组中查找最近元素的最快方法

Python 在实数数组中查找最近元素的最快方法,python,search,tree,binary-search-tree,kdtree,Python,Search,Tree,Binary Search Tree,Kdtree,对于每个元素的给定实数数组,找到比当前元素少不超过0.5的元素数,然后写入新数组 例如: 原始阵列: [0.1, 0.7, 0.8, 0.85, 0.9, 1.5, 1.7] 结果数组: [0, 0, 1, 2, 3, 0, 1] 解决这个问题的算法和方法是什么 重要的是,仅在负方向选择点的邻域,这使得不可能使用Kdtree或Balltree算法 我所有的问题都在于我的编码尝试。这将解决您的特定任务 def find_nearest_element(original

对于每个元素的给定实数数组,找到比当前元素少不超过
0.5
的元素数,然后写入新数组

例如:

原始阵列:

[0.1, 0.7, 0.8, 0.85, 0.9, 1.5, 1.7]
结果数组:

[0,   0,   1,   2,    3,   0,   1]
解决这个问题的算法和方法是什么

重要的是,仅在负方向选择点的邻域,这使得不可能使用
Kdtree
Balltree
算法


我所有的问题都在于我的编码尝试。

这将解决您的特定任务

def find_nearest_element(original_array):
    result_array = []
    for e in original_array:
        result_array.append(len(original_array[(e-0.5 < original_array) & (e > original_array)]))
    return result_array

original_array = np.array([0.1, 0.7, 0.8, 0.85, 0.9, 1.5, 1.7])
print(find_nearest_element(original_array))
编辑:对于较小的阵列(约len 10000),使用掩码的速度明显快于使用numba的版本。对于较大的阵列,使用Numba的版本更快。因此,这取决于您希望处理的阵列的大小

某些运行时比较(以秒为单位):


我的设备上的盈亏平衡点大约为10000(两者都需要约0.33秒)。

尽管下面的方法使用简单的逻辑并且易于编写,但速度很慢。我们可以通过使用修饰函数来加速它。这将把简单的循环任务加速到接近汇编语言的速度

使用
pip安装Numba
安装Numba

from numba import jit
import numpy as np

# Create a numpy array of length 10000 with float values between 0 and 10
random_values = np.random.uniform(0.0,10.0,size=(100*100,))

@jit(nopython=True, nogil=True)
def find_nearest(input):
  result = []
  for e in input:
    counter = 0
    for j in input:
      if j >= (e-0.5) and j < e:
        counter += 1
    result.append(counter)
  return result

result = find_nearest(random_values)
返回:

[0, 0, 1, 2, 3, 0, 1]

对于有序阵列,这个问题很容易解决。你只需向后搜索并计算所有大于实际数字半径的数字。如果这个条件不再满足,你可以打破内部循环(这节省了很多时间)

示例

import numpy as np
from scipy import spatial
import numba as nb

@nb.njit(parallel=True)
def get_counts_2(Points_sorted,ind,r):
  counts=np.zeros(Points_sorted.shape[0],dtype=np.int64)
  for i in nb.prange(0,Points_sorted.shape[0]):
    count=0
    for j in range(i-1,0,-1):
      if (Points_sorted[i]-r<Points_sorted[j]):
        count+=1
      else:
        break
    counts[ind[i]]=count
  return counts

你能告诉我你有什么问题吗?我的问题在于我的代码尝试。数字总是被排序吗?@max9111不,它们没有被排序。这是一个非常缓慢的决定,有困难O(n^2)。在帖子中没有提到速度优化。。。。是的,这可能不是最快的。也不是他想要的,因为他只想将当前数字与数组左侧进行比较。真的吗?我不是这样理解这个问题的。。。。“仅在负方向上选择点的邻域”表示搜索邻域距离为0.5,但仅限于搜索x-0.5范围内的值(其中x为目标值)。我已经修改了我的答案,以获得更好的速度优化。真的很有趣,谢谢你的时间比较!(虽然,也许这不应该格式化为代码块?)我也这么认为。但是如果我不把它放在代码块中,两行之间的距离会变得非常大:/至少它是一个脚本的输出^^你的意思是“两行都需要大约0.33秒”吗?
test = [0.1, 0.7, 0.8, 0.85, 0.9, 1.5, 1.7]
result = find_nearest(test)
print result
[0, 0, 1, 2, 3, 0, 1]
import numpy as np
from scipy import spatial
import numba as nb

@nb.njit(parallel=True)
def get_counts_2(Points_sorted,ind,r):
  counts=np.zeros(Points_sorted.shape[0],dtype=np.int64)
  for i in nb.prange(0,Points_sorted.shape[0]):
    count=0
    for j in range(i-1,0,-1):
      if (Points_sorted[i]-r<Points_sorted[j]):
        count+=1
      else:
        break
    counts[ind[i]]=count
  return counts
r=0.001
Points=np.random.rand(1_000_000)

t1=time.time()
ind=np.argsort(Points)
Points_sorted=Points[ind]
counts=get_counts_2(Points_sorted,ind,r)
print(time.time()-t1)
#0.29s