加快Numpy / Python中的最小搜索速度

时间:2012-11-07 15:14:23

标签: python numpy scipy

我有两个浮动数组,想要找到在一定范围内匹配的数据点。 这是我到目前为止所得到的:

import numpy as np

for vx in range(len(arr1)):
    match = (np.abs(arr2-arr1[vx])).argmin()
    if abs(arr1[vx]-arr2[match])<0.375:
        point = arr2[match]

问题是arr1包含150000个元素,arr2包含110000个元素。这需要花费大量时间。你有建议加快速度吗?

2 个答案:

答案 0 :(得分:3)

除了不进行矢量化之外,您当前的搜索是(n * m),其中n是arr2的大小,m是arr1的大小。在这些类型的搜索中,有助于对arr1或arr2进行排序,以便您可以使用二进制搜索。排序最终是最慢的步骤,但如果m很大,它仍然会更快,因为n * log(n)排序比(n * m)快。

以下是使用排序数组以矢量化方式进行搜索的方法:

def find_closest(A, target):
    #A must be sorted
    idx = A.searchsorted(target)
    idx = np.clip(idx, 1, len(A)-1)
    left = A[idx-1]
    right = A[idx]
    idx -= target - left < right - target
    return A[idx]

arr2.sort()
closest = find_closest(arr2, arr1)
closest = np.where(abs(closest - arr1) < .375, closest, np.nan)

答案 1 :(得分:0)

使用numpy的整个想法是避免使用循环进行计算。

通过数组计算可以轻松实现指定提取满足条件的新数组的条件。这是一个从数组a中提取值的示例,它满足该元素与数组b中相应元素的绝对差值小于0.75的条件: -

a = array([1, 0, 0.5, 1.2])

b = array([1.2, 1.1, 1.3, 1.4])

c = a[abs(a-b)<0.75]

这给了我们

array([ 1. ,  1.2])