gpt4 book ai didi

python - 使用 Numpy 高效计算欧氏距离矩阵

转载 作者:太空狗 更新时间:2023-10-29 17:09:57 25 4
gpt4 key购买 nike

我在二维空间中有一组点,需要计算每个点到其他点的距离。

我的点数相对较少,可能最多 100 个。但由于我需要经常快速地进行操作以确定这些移动点之间的关系,而且我知道遍历这些点可能与 O(n^2) 复杂度一样糟糕,我正在寻找利用 numpy 矩阵魔法(或 scipy)的方法。

在我的代码中,每个对象的坐标都存储在它的类中。但是,当我更新类坐标时,我也可以在一个 numpy 数组中更新它们。

class Cell(object):
"""Represents one object in the field."""
def __init__(self,id,x=0,y=0):
self.m_id = id
self.m_x = x
self.m_y = y

我想创建一个欧几里德距离矩阵来防止重复,但也许您有更聪明的数据结构。

我也乐于接受指向漂亮算法的指针。

另外,我注意到有类似的问题涉及欧氏距离和 numpy,但没有找到任何直接解决有效填充完整距离矩阵的问题。

最佳答案

您可以利用 complex 类型:

# build a complex array of your cells
z = np.array([complex(c.m_x, c.m_y) for c in cells])

第一个解决方案

# mesh this array so that you will have all combinations
m, n = np.meshgrid(z, z)
# get the distance via the norm
out = abs(m-n)

第二种方案

网格划分是主要思想。但是 numpy 很聪明,所以您不必生成 mn。只需使用 z 的转置版本计算差异即可。网格是自动完成的:

out = abs(z[..., np.newaxis] - z)

第三种方案

而如果将z直接设置为二维数组,则可以使用z.T代替怪异的z[..., np.newaxis ]。所以最后,您的代码将如下所示:

z = np.array([[complex(c.m_x, c.m_y) for c in cells]]) # notice the [[ ... ]]
out = abs(z.T-z)

例子

>>> z = np.array([[0.+0.j, 2.+1.j, -1.+4.j]])
>>> abs(z.T-z)
array([[ 0. , 2.23606798, 4.12310563],
[ 2.23606798, 0. , 4.24264069],
[ 4.12310563, 4.24264069, 0. ]])

作为补充,您可能希望之后删除重复项,取上面的三角形:

>>> np.triu(out)
array([[ 0. , 2.23606798, 4.12310563],
[ 0. , 0. , 4.24264069],
[ 0. , 0. , 0. ]])

一些基准

>>> timeit.timeit('abs(z.T-z)', setup='import numpy as np;z = np.array([[0.+0.j, 2.+1.j, -1.+4.j]])')
4.645645342274779
>>> timeit.timeit('abs(z[..., np.newaxis] - z)', setup='import numpy as np;z = np.array([0.+0.j, 2.+1.j, -1.+4.j])')
5.049334864854522
>>> timeit.timeit('m, n = np.meshgrid(z, z); abs(m-n)', setup='import numpy as np;z = np.array([0.+0.j, 2.+1.j, -1.+4.j])')
22.489568296184686

关于python - 使用 Numpy 高效计算欧氏距离矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22720864/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com