几年前,有人posted对活动状态食谱作比较,三个python/NumPy函数;其中每个接受相同的参数并返回相同的结果,距离矩阵。为什么在这里循环跳动索引?
其中两个是从公开资料中获得的;他们都是 - 或者他们似乎是我惯用的numpy代码。创建距离矩阵所需的重复计算由numpy的优雅索引语法驱动。这里是其中的一个:
from numpy.matlib import repmat, repeat
def calcDistanceMatrixFastEuclidean(points):
numPoints = len(points)
distMat = sqrt(sum((repmat(points, numPoints, 1) -
repeat(points, numPoints, axis=0))**2, axis=1))
return distMat.reshape((numPoints,numPoints))
使用一个循环(这显然是一个很大的循环考虑到的只是1000的2D点的距离矩阵,有一万个条目)第三创建距离矩阵。乍一看,这个函数在我看来像我在学习NumPy时编写的代码,我会先编写NumPy代码,然后逐行翻译它。
活动状态帖子发布几个月后,比较三者的性能测试结果在NumPy邮件列表上发布并在thread中讨论。
与事实上的循环功能显著跑赢另外两个:在线程
from numpy import mat, zeros, newaxis
def calcDistanceMatrixFastEuclidean2(nDimPoints):
nDimPoints = array(nDimPoints)
n,m = nDimPoints.shape
delta = zeros((n,n),'d')
for d in xrange(m):
data = nDimPoints[:,d]
delta += (data - data[:,newaxis])**2
return sqrt(delta)
一位与会者(凯尔·Mierle)提供一个理由,这可能是真实的:
我怀疑这会更快的原因是 它具有更好的地方性,完全完成一个相对较小的工作集上的计算,然后再转到下一个工作集之一。一行 必须重复将可能较大的MxN阵列拉入处理器。
通过这张海报自己的帐户,他的评论只是一个怀疑,似乎并没有进一步讨论。
有关如何解释这些结果的其他想法?
特别是,有没有一个有用的规则 - 关于什么时候循环和何时索引 - 可以从这个例子中提取作为编写numpy代码的指导?
对于那些不熟悉NumPy的人,或者没有看过代码的人,这种比较不是基于边缘案例 - 如果是的话,这对我来说肯定不会那么有趣。相反,这种比较涉及在矩阵计算中执行共同任务的功能(即,创建给定两个前件的结果数组)。而且,每个函数都是由最常见的numpy内建插件组成的。
非常有帮助,谢谢。从我+1。 – doug 2010-08-19 07:31:20