在一些在线研究(1,2,numpy,scipy,scikit,math)之后,我找到了几种计算 Euclidean Distance in Python 的方法:
# 1
numpy.linalg.norm(a-b)
# 2
distance.euclidean(vector1, vector2)
# 3
sklearn.metrics.pairwise.euclidean_distances
# 4
sqrt((xa-xb)^2 + (ya-yb)^2 + (za-zb)^2)
# 5
dist = [(a - b)**2 for a, b in zip(vector1, vector2)]
dist = math.sqrt(sum(dist))
# 6
math.hypot(x, y)
我想知道是否有人可以提供关于 efficiency 和 precision 中哪一个(或我没有找到的任何其他)被认为是最佳的洞察力 . 如果有人知道讨论该主题的任何资源也会很棒 .
我感兴趣的上下文是计算数字元组对之间的欧几里德距离,例如, (52, 106, 35, 12)
和 (33, 153, 75, 10)
之间的距离 .
3 回答
结论第一:
从使用
timeit
进行效率测试的测试结果,我们可以得出结论 regarding the efficiency :Method5 (zip, math.sqrt) > Method1 (numpy.linalg.norm) > Method2 (scipy.spatial.distance) > Method3 (sklearn.metrics.pairwise.euclidean_distances )
虽然我没有真正测试你的
Method4
,因为它不适合一般情况,它通常相当于Method5
.其余的,令人惊讶的是,
Method5
是最快的 . 而对于使用numpy
的Method1
,正如我们所预期的那样,在C中进行了大量优化,是第二快的 .对于
scipy.spatial.distance
,如果直接进入函数定义,您将看到它实际上正在使用numpy.linalg.norm
,除了它将在实际numpy.linalg.norm
之前对两个输入向量执行验证 . 这就是为什么它稍微慢了numpy.linalg.norm
.最后为
sklearn
,根据文档:由于在您的问题中您希望使用一组固定的数据,因此不会反映此实现的优势 . 由于性能和精度之间的权衡,它在所有方法中也提供了最差的精度 .
Regarding the precision , Method5=Metho1=Method2>Method3
效率测试脚本:
效率测试输出:
精密测试脚本和结果:
我不知道精度和速度如何与您提到的其他库相比,但您可以使用内置的
math.hypot()
函数为2D矢量执行此操作:作为一般的经验法则,尽可能坚持
scipy
和numpy
实现,因为它们被矢量化并且比本机Python代码快得多 . (主要原因是:在C中实现,向量化消除了循环所做的类型检查开销 . )(旁白:我的答案不包括这里的精度,但我认为同样的原则适用于效率的精确度 . )
作为一个奖励,我重新使用IPython解释器,秘诀是使用
%prun
线魔术 .%prun
的作用是告诉你函数调用需要多长时间才能运行,包括一些跟踪以找出瓶颈所在的位置 . 在这种情况下,scipy.spatial.distance.euclidean
和numpy.linalg.norm
实现都非常快 . 假设您定义了一个函数dist(vect1, vect2)
,您可以使用相同的IPython魔术调用进行概要分析 . 作为另一个额外的好处,%prun
也可以在Jupyter笔记本内部工作,你可以做%%prun
分析整个代码单元,而不仅仅是一个函数,只需将%%prun
作为该单元格的第一行 .