根据另一个数组中的所有值查找一个数组的最近索引-Python/NumPy
我有一个复数列表,我想在另一个复数列表中找到最接近的值 我目前使用numpy的方法: 不幸的是,对于大量的值来说,这需要时间。 是否有一种更快或更“pythonian”的方法将myArray中的每个值与refArray中最接近的值进行匹配 仅供参考:我的脚本中不一定需要numpy根据另一个数组中的所有值查找一个数组的最近索引-Python/NumPy,python,arrays,list,numpy,Python,Arrays,List,Numpy,我有一个复数列表,我想在另一个复数列表中找到最接近的值 我目前使用numpy的方法: 不幸的是,对于大量的值来说,这需要时间。 是否有一种更快或更“pythonian”的方法将myArray中的每个值与refArray中最接近的值进行匹配 仅供参考:我的脚本中不一定需要numpy 重要提示:myArray和refArray的顺序都很重要,不应更改。如果要应用排序,则应以某种方式保留原始索引。以下是一种基于- 时间安排和核查- In [188]: refArray = np.random.rand
重要提示:myArray和refArray的顺序都很重要,不应更改。如果要应用排序,则应以某种方式保留原始索引。以下是一种基于- 时间安排和核查-
In [188]: refArray = np.random.random(16)
...: myArray = np.random.random(1000)
...:
In [189]: %timeit org_app(myArray, refArray)
100 loops, best of 3: 1.95 ms per loop
In [190]: %timeit closest_argmin(myArray, refArray)
10000 loops, best of 3: 36.6 µs per loop
In [191]: np.allclose(closest_argmin(myArray, refArray), org_app(myArray, refArray))
Out[191]: True
50x+
为发布的示例加速,希望为更大的数据集加速 答案比@Divakar短得多,也使用广播,甚至比@Divakar快一点:
abs(myArray[:, None] - refArray[None, :]).argmin(axis=-1)
就时间复杂度而言,滑动窗口可能是最有效的。我看不出滑动窗口比当前解决方案更有效。据我所知,目前的解决方案是O(n),这是最好的希望。然后,为了最小化时间常数,需要做一些权衡。但这取决于你的大案子是否会毁掉你的记忆。如果不是内存问题,可能会从使用广播中获得一点好处,并使用更多的
numpy
计算,但如果RAM内存是一个问题,那么这也可能会降低您的速度。@JohanL RAM不是一个问题,不幸的是时间是一个问题。这个简单的循环是我能想到的最简单也是最好的方法。。不幸的是,当数组大小为ref=64,值为200000时,匹配需要10秒以上的时间,目标值可能不到1秒……您可以尝试scipy.space.KDTree.query
。您真的需要np.abs
?我想你也可以使用(A-sorted\u B[sorted\u idx-1]
或(A
。此外,我不认为使用np.allclose
来比较索引数组是一个非常有效的解决方案。与中的cKDTree
相比,谁不直接使用np.sort对B进行排序?@Anush,因为我在最后一步需要sidx_B
。
def org_app(myArray, refArray):
out1 = np.empty(myArray.size, dtype=int)
for i, value in enumerate(myArray):
# find_nearest from posted question
index = find_nearest(refArray, value)
out1[i] = index
return out1
In [188]: refArray = np.random.random(16)
...: myArray = np.random.random(1000)
...:
In [189]: %timeit org_app(myArray, refArray)
100 loops, best of 3: 1.95 ms per loop
In [190]: %timeit closest_argmin(myArray, refArray)
10000 loops, best of 3: 36.6 µs per loop
In [191]: np.allclose(closest_argmin(myArray, refArray), org_app(myArray, refArray))
Out[191]: True
abs(myArray[:, None] - refArray[None, :]).argmin(axis=-1)