Python Numpy中坐标距离的矢量化

Python Numpy中坐标距离的矢量化,python,numpy,vectorization,Python,Numpy,Vectorization,我试图通过矢量化来理解Numpy。我正试图找到最快的函数来实现它 def get_distances3(coordinates): return np.linalg.norm( coordinates[:, None, :] - coordinates[None, :, :], axis=-1) coordinates = np.random.rand(1000, 3) %timeit get_distances3(coordinates) 上述功能需

我试图通过矢量化来理解Numpy。我正试图找到最快的函数来实现它

def get_distances3(coordinates):
    return np.linalg.norm(
        coordinates[:, None, :] - coordinates[None, :, :],
        axis=-1)
coordinates = np.random.rand(1000, 3)
%timeit get_distances3(coordinates)

上述功能需要10个循环,每个循环的最佳时间为3:35.4毫秒。在numpy库中,还有一个np.vectorize选项可以执行此操作

def get_distances4(coordinates):
  return np.vectorize(coordinates[:, None, :] - coordinates[None, :, :],axis=-1)

%timeit get_distances4(coordinates)
我尝试了下面的np.vectorize,但最终出现了以下错误

TypeError:\uuuu init\uuuuuuuu()获得意外的关键字参数“axis”


如何在get_Distance4中找到矢量化?我应该如何编辑lsat代码以避免错误?我从未使用过np.vectorize,因此可能缺少一些内容。

您没有正确调用
np.vectorize()。我建议参考

Vectorize将编写用于对标量值进行操作的函数作为其参数,并将其转换为可根据Numpy广播规则对数组中的值进行矢量化的函数。它基本上类似于Numpy数组的花式
map()

i、 e.正如您所知,Numpy已经有许多常用函数的内置矢量化版本,但是如果您有一些自定义函数,如“my_special_function(x)”,并且希望能够在Numpy数组上调用它,您可以使用
my_special_function\u ufunc=np.vectorize(my_special_function)

在上面的示例中,您可以将距离函数“矢量化”,如:

>>> norm = np.linalg.norm
>>> get_distance4 = np.vectorize(lambda a, b: norm(a - b))
>>> get_distance4(coordinates[:, None, :], coordinates[None, :, :])
但是,您会发现这是非常缓慢的:

>>> %timeit get_distance4(coordinates[:, None, :], coordinates[None, :, :])
1 loop, best of 3: 10.8 s per loop
这是因为您的第一个示例
get\u distance 3
已经在使用Numpy内置的这些操作的快速实现,而
np.vectorize
版本需要调用我定义了大约3000次的Python函数

事实上,根据文件:

提供矢量化功能主要是为了方便,而不是为了性能。该实现本质上是一个for循环

如果您想要一个可能更快的函数来转换向量之间的距离,您可以使用:


值得注意的是,这有一个不同的回报形式。它使用的不是1000x1000数组,而是压缩格式,不包括
i=j
条目和
i>j
条目。如果您希望,然后可以使用转换回方形矩阵格式。

您的第一个解决方案已经矢量化,不需要
np.vectorize()
是否可以通过np.vectorize()进行矢量化?如果是,怎么做?@enes也许你可以提供一个后续的例子。通过使用
np.vectorize()
您的第一个示例还没有实现的目标是什么?
>>> %timeit get_distances3(coordinates)
10 loops, best of 3: 24.2 ms per loop
>>> %timeit distance.pdist(coordinates)
1000 loops, best of 3: 1.77 ms per loop