使用numpy在python中进行向量化空间距离

使用numpy在python中进行向量化空间距离,第1张

使用numpy在python中进行向量化空间距离

有一个

eucl_dist

软件包(免责声明:我是它的作者),其中基本上包含两种方法来解决计算平方欧几里德距离的问题,该方法比的效率更高
SciPy'scdist
,特别是对于大型数组(具有相当大的列数)。

我们将使用其中的一些代码

sourcepre
来适应此处的问题,从而为我们提供两种方法。

方法1

wiki contents
,我们可以利用
matrix-multiplication
一些
NumPy specificimplementations
我们的第一个方法,像这样-

def pdist_squareformed_numpy(a):    a_sumrows = np.einsum('ij,ij->i',a,a)    dist = a_sumrows[:,None] + a_sumrows -2*np.dot(a,a.T)    np.fill_diagonal(dist,0)    return dist

方法#2

另一种方法是创建输入数组的“扩展”版本,在github源代码链接中再次进行了详细讨论,以获取我们的第二种方法,这种方法适用于较小的列,例如此处所示-

def ext_arrs(A,B, precision="float64"):    nA,dim = A.shape    A_ext = np.ones((nA,dim*3),dtype=precision)    A_ext[:,dim:2*dim] = A    A_ext[:,2*dim:] = A**2    nB = B.shape[0]    B_ext = np.ones((dim*3,nB),dtype=precision)    B_ext[:dim] = (B**2).T    B_ext[dim:2*dim] = -2.0*B.T    return A_ext, B_extdef pdist_squareformed_numpy_v2(a):    A_ext, B_ext = ext_arrs(a,a)    dist = A_ext.dot(B_ext)    np.fill_diagonal(dist,0)    return dist

请注意,这些给出了平方欧几里德距离。因此,对于实际距离,我们想使用

np.sqrt()
是否需要的最终输出。

样品运行-

In [380]: np.random.seed(0)     ...: a = np.random.rand(5,3)In [381]: from scipy.spatial.distance import cdistIn [382]: cdist(a,a)Out[382]: array([[0.  , 0.29, 0.42, 0.2 , 0.57],       [0.29, 0.  , 0.58, 0.42, 0.76],       [0.42, 0.58, 0.  , 0.45, 0.9 ],       [0.2 , 0.42, 0.45, 0.  , 0.51],       [0.57, 0.76, 0.9 , 0.51, 0.  ]])In [383]: np.sqrt(pdist_squareformed_numpy(a))Out[383]: array([[0.  , 0.29, 0.42, 0.2 , 0.57],       [0.29, 0.  , 0.58, 0.42, 0.76],       [0.42, 0.58, 0.  , 0.45, 0.9 ],       [0.2 , 0.42, 0.45, 0.  , 0.51],       [0.57, 0.76, 0.9 , 0.51, 0.  ]])In [384]: np.sqrt(pdist_squareformed_numpy_v2(a))Out[384]: array([[0.  , 0.29, 0.42, 0.2 , 0.57],       [0.29, 0.  , 0.58, 0.42, 0.76],       [0.42, 0.58, 0.  , 0.45, 0.9 ],       [0.2 , 0.42, 0.45, 0.  , 0.51],       [0.57, 0.76, 0.9 , 0.51, 0.  ]])

时间

10k
点-

In [385]: a = np.random.rand(10000,3)In [386]: %timeit cdist(a,a)1 loop, best of 3: 309 ms per loop# Approach #1In [388]: %timeit pdist_squareformed_numpy(a) # squared eucl distances1 loop, best of 3: 668 ms per loopIn [389]: %timeit np.sqrt(pdist_squareformed_numpy(a)) # actual eucl distances1 loop, best of 3: 812 ms per loop# Approach #2In [390]: %timeit pdist_squareformed_numpy_v2(a) # squared eucl distances1 loop, best of 3: 237 ms per loopIn [391]: %timeit np.sqrt(pdist_squareformed_numpy_v2(a)) # actual eucl distances1 loop, best of 3: 395 ms per loop

第二种方法似乎

cdist
在性能上接近一种!



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5616709.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存