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