亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

python:計算向量到矩陣每一行的歐氏距離的最快方法?

python:計算向量到矩陣每一行的歐氏距離的最快方法?

冉冉說 2023-06-13 16:27:47
考慮這個 python 代碼,我在其中嘗試計算向量到矩陣每一行的歐幾里距離。與我能找到的使用 Tullio.jl 的最佳 Julia 版本相比,它非常慢。python 版本需要30s而 Julia 版本只需要75ms。我確信我在 Python 方面沒有做得最好。有更快的解決方案嗎?歡迎使用 Numba 和 numpy 解決方案。import numpy as np# generatea = np.random.rand(4000000, 128)b = np.random.rand(128)print(a.shape)print(b.shape)def lin_norm_ever(a, b):    return np.apply_along_axis(lambda x: np.linalg.norm(x - b), 1, a)import timet = time.time()res = lin_norm_ever(a, b)print(res.shape)elapsed = time.time() - tprint(elapsed)朱莉婭版本using Tulliofunction comp_tullio(a, c)    dist = zeros(Float32, size(a, 2))    @tullio dist[i] = (c[j] - a[j,i])^2    distend@time comp_tullio(a, c)@benchmark comp_tullio(a, c) # 75ms on my computer
查看完整描述

1 回答

?
慕沐林林

TA貢獻2016條經驗 獲得超9個贊

為了獲得最佳性能,我將在此示例中使用 Numba。我還添加了來自 Divakars 鏈接答案的 2 種方法以進行比較。


代碼


import numpy as np

import numba as nb

from scipy.spatial.distance import cdist


@nb.njit(fastmath=True,parallel=True,cache=True)

def dist_1(mat,vec):

    res=np.empty(mat.shape[0],dtype=mat.dtype)

    for i in nb.prange(mat.shape[0]):

        acc=0

        for j in range(mat.shape[1]):

            acc+=(mat[i,j]-vec[j])**2

        res[i]=np.sqrt(acc)

    return res


#from https://stackoverflow.com/a/52364284/4045774

def dist_2(mat,vec):

    return cdist(mat, np.atleast_2d(vec)).ravel()


#from https://stackoverflow.com/a/52364284/4045774

def dist_3(mat,vec):

    M = mat.dot(vec)

    d = np.einsum('ij,ij->i',mat,mat) + np.inner(vec,vec) -2*M

    return np.sqrt(d)

時序


#Float64

a = np.random.rand(4000000, 128)

b = np.random.rand(128)

%timeit dist_1(a,b)

#122 ms ± 3.86 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit dist_2(a,b)

#484 ms ± 3.02 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit dist_3(a,b)

#432 ms ± 14.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)


#Float32

a = np.random.rand(4000000, 128).astype(np.float32)

b = np.random.rand(128).astype(np.float32)

%timeit dist_1(a,b)

#68.6 ms ± 414 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit dist_2(a,b)

#2.2 s ± 32.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

#looks like there is a costly type-casting to float64

%timeit dist_3(a,b)

#228 ms ± 8.13 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)


查看完整回答
反對 回復 2023-06-13
  • 1 回答
  • 0 關注
  • 133 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號