为了账号安全,请及时绑定邮箱和手机立即绑定

矩阵向量差的有效元素 argmin

矩阵向量差的有效元素 argmin

临摹微笑 2024-01-04 17:22:08
假设一个数组a.shape == (N, M)和一个向量v.shape == (N,)。目标是计算argmin从每个元素中减去abs的- 也就是说,vaout = np.zeros(N, M)for i in range(N):    for j in range(M):        out[i, j] = np.argmin(np.abs(a[i, j] - v))我通过进行了矢量化实现np.matlib.repmat,它速度更快,但需要O(M*N^2)内存,这在实践中是不可接受的。计算仍然在 CPU 上完成,因此最好的选择似乎是在 C 中实现 for 循环作为扩展,但也许 Numpy 已经实现了这种逻辑。可以?有任何可用的 Numpy 函数可以有效地实现上述功能吗?
查看完整描述

1 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

受到 的启发this post,我们可以利用np.searchsorted-

def find_closest(a, v):

    sidx = v.argsort()

    v_s = v[sidx]

    idx = np.searchsorted(v_s, a)

    idx[idx==len(v)] = len(v)-1

    idx0 = (idx-1).clip(min=0)

    

    m = np.abs(a-v_s[idx]) >= np.abs(v_s[idx0]-a)

    m[idx==0] = 0

    idx[m] -= 1

    out = sidx[idx]

    return out

更多性能。numexpr在大型数据集上进行提升:


import numexpr as ne


def find_closest_v2(a, v):

    sidx = v.argsort()

    v_s = v[sidx]

    idx = np.searchsorted(v_s, a)

    idx[idx==len(v)] = len(v)-1

    idx0 = (idx-1).clip(min=0)

    

    p1 = v_s[idx]

    p2 = v_s[idx0]

    m = ne.evaluate('(idx!=0) & (abs(a-p1) >= abs(p2-a))', {'p1':p1, 'p2':p2, 'idx':idx})

    idx[m] -= 1

    out = sidx[idx]

    return out

时间安排


设置 :


N,M = 500,100000

a = np.random.rand(N,M)

v = np.random.rand(N)


In [22]: %timeit find_closest_v2(a, v)

4.35 s ± 21.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)


In [23]: %timeit find_closest(a, v)

4.69 s ± 173 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)


查看完整回答
反对 回复 2024-01-04
  • 1 回答
  • 0 关注
  • 109 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信