代码之家  ›  专栏  ›  技术社区  ›  00__00__00

查找并替换numpy数组中与第二个数组最接近的值

  •  1
  • 00__00__00  · 技术社区  · 7 年前

    np.array ( vec 我想替换中的每个值 vec 使用较短数组中最接近的值 vals .

    replaced_vals=vals[np.argmin(np.abs(vec[:, np.newaxis] - vals), axis=0)]
    

    但它不起作用,因为 vec

    示例输入

    vec = np.array([10.1,10.7,11.4,102,1100]
    vals = np.array([10.0,11.0,100.0])
    

    期望输出:

    replaced_vals = [10.0,11.0,11.0,100.0,100.0]
    
    3 回复  |  直到 7 年前
        1
  •  2
  •   jpp    7 年前

    如果你的 vals 数组已排序,内存效率更高,而且通常可能更高效,通过 np.searchsorted

    def jpp(vec, vals):
        ss = np.searchsorted(vals, vec)
        a = vals[ss - 1]
        b = vals[np.minimum(len(vals) - 1, ss)]
        return np.where(np.fabs(vec - a) < np.fabs(vec - b), a, b)
    
    vec = np.array([10.1,10.7,11.4,102,1100])
    vals = np.array([10.0,11.0,100.0])
    
    print(jpp(vec, vals))
    
    [  10.   11.   11.  100.  100.]
    

    绩效基准

    # Python 3.6.0, NumPy 1.11.3
    
    n = 10**6
    vec = np.array([10.1,10.7,11.4,102,1100]*n)
    vals = np.array([10.0,11.0,100.0])
    
    # @ThomasPinetz's solution, memory inefficient
    def tho(vec, vals):
        return vals[np.argmin(np.abs(vec[:, np.newaxis] - vals), axis=1)]
    
    def jpp(vec, vals):
        ss = np.searchsorted(vals, vec)
        a = vals[ss - 1]
        b = vals[np.minimum(len(vals) - 1, ss)]
        return np.where(np.fabs(vec - a) < np.fabs(vec - b), a, b)
    
    # @Divakar's solution, adapted from first related Q&A link
    def diva(A, B):
        L = B.size
        sorted_idx = np.searchsorted(B, A)
        sorted_idx[sorted_idx==L] = L-1
        mask = (sorted_idx > 0) & \
        ((np.abs(A - B[sorted_idx-1]) < np.abs(A - B[sorted_idx])) )
        return B[sorted_idx-mask]
    
    assert np.array_equal(tho(vec, vals), jpp(vec, vals))
    assert np.array_equal(tho(vec, vals), diva(vec, vals))
    
    %timeit tho(vec, vals)   # 366 ms per loop
    %timeit jpp(vec, vals)   # 295 ms per loop
    %timeit diva(vec, vals)  # 334 ms per loop
    

    有关的提问,;A.

    1. Find nearest indices for one array against all values in another array - Python / NumPy
    2. Find nearest value in numpy array
        2
  •  2
  •   Thomas Pinetz    7 年前

    replaced_vals=vals[np.argmin(np.abs(vec[:, np.newaxis] - vals), axis=1)]
    

    array([  10.,   11.,   11.,  100.,  100.])
    
        3
  •  1
  •   B. M.    7 年前

    如果 vals 分类后, x_k vec 必须四舍五入到 y_i 如果:

                               (y_(i-1)+y_i)/2 <= x_k < (y_i+y_(i+1))/2.    
    

    因此,另一个解决方案是使用 np.searchsorted ,但最大限度地减少操作,速度至少提高两倍:

    def bm(vec, vals):
        half = vals.copy() / 2
        half[:-1] += half[1:]
        half[-1] = np.inf
        ss = np.searchsorted(half,vec)
        return vals[ss]
    
    %timeit bm(vec, vals)  # 84 ms per loop
    

    如果 您还可以使用排序完成此项工作 numba

    from numba import njit
    @njit
    def bmm(vec,vals):
        half=vals.copy()/2
        half[:-1] += half[1:]
        half[-1]=np.inf
        res=np.empty_like(vec)
        i=0
        for k in range(vec.size):
            while half[i]<vec[k]:
                i+=1
            res[k]=vals[i]
        return res
    
    %timeit bmm(vec, vals)  # 31 ms per loop