python – einsum和距离计算
发布时间:2020-12-20 11:44:39 所属栏目:Python 来源:网络整理
导读:我已经搜索了一个解决方案来确定使用einsum的numpy数组的距离,这些数组的行数不相同,但列数相等.我尝试了各种组合,但我能成功的唯一方法是使用以下代码.我显然缺少一些东西,文献和众多线程并没有让我更接近解决方案.我希望找到一个通用性,使得起源可以是任何
我已经搜索了一个解决方案来确定使用einsum的numpy数组的距离,这些数组的行数不相同,但列数相等.我尝试了各种组合,但我能成功的唯一方法是使用以下代码.我显然缺少一些东西,文献和众多线程并没有让我更接近解决方案.我希望找到一个通用性,使得起源可以是任何数字的目标数组的任何数字.我只使用2D数组,无意将其扩展到其他维度.我也熟悉pdist和cdist以及其他达到我想要的解决方案的方法,但是,我只对einsum感兴趣,因为我想要完善我的一些例子.任何帮助,将不胜感激.
import numpy as np origs = np.array([[0.,0.],[1.,[0.,1.],1.]]) dests = np.asarray([[4.,[2.,2.],3.],5.]]) for i in origs: d =np.sqrt(np.einsum("ij,ij->i",i-dests,i-dests)) print("orig {}...dist: {}".format(i,d)) 我正在寻找以下结果…… orig [ 0. 0.]...dist: [ 4. 1.41421356 2.82842712 3.60555128 5. ] orig [ 1. 0.]...dist: [ 3. 1. 2.23606798 3.16227766 5.09901951] orig [ 0. 1.]...dist: [ 4.12310563 1. 2.23606798 2.82842712 4. ] orig [ 1. 1.]...dist: [ 3.16227766 0. 1.41421356 2.23606798 4.12310563] 解决方法
如果我正确理解了这个问题,那么在考虑2D数组时,你发布的for循环代码对我来说是通用的.现在,如果您希望通过一次调用
np.einsum 来获得通用的矢量化解决方案,那么您可以将
broadcasting 引入游戏,就像这样 –
d_all = np.sqrt(np.einsum('ijk->ij',(origs[:,None,:] - dests)**2)) 样品运行 – In [85]: origs = np.array([[0.,1.]]) ...: dests = np.asarray([[4.,5.]]) ...: In [86]: for i in origs: ...: d =np.sqrt(np.einsum("ij,i-dests)) ...: print(d) ...: [ 4. 1.41421356 2.82842712 3.60555128 5. ] [ 3. 1. 2.23606798 3.16227766 5.09901951] [ 4.12310563 1. 2.23606798 2.82842712 4. ] [ 3.16227766 0. 1.41421356 2.23606798 4.12310563] In [87]: np.sqrt(np.einsum('ijk->ij',:] - dests)**2)) Out[87]: array([[ 4.,1.41421356,2.82842712,3.60555128,5. ],[ 3.,1.,2.23606798,3.16227766,5.09901951],[ 4.12310563,4. ],[ 3.16227766,0.,4.12310563]]) 根据 subts = origs[:,:] - dests d_all = np.sqrt(np.einsum('ijk,ijk->ij',subts,subts)) 这是一个运行时测试,将其与之前在np.einsum之外进行平方的方法进行比较 – In [7]: def all_einsum(origs,dests): ...: subts = origs[:,:] - dests ...: return np.sqrt(np.einsum('ijk,subts)) ...: ...: def partial_einsum(origs,dests): ...: return np.sqrt(np.einsum('ijk->ij',:] - dests)**2)) ...: In [8]: origs = np.random.rand(400,100) In [9]: dests = np.random.rand(500,100) In [10]: %timeit all_einsum(origs,dests) 10 loops,best of 3: 139 ms per loop In [11]: %timeit partial_einsum(origs,dests) 1 loops,best of 3: 251 ms per loop (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |