给定一个坐标列表,计算每对点之间距离的最有效方法是什么?

时间:2018-01-05 11:11:49

标签: python python-3.x

我有一个坐标列表(x,y)。

计算每个坐标之间距离的最有效方法是什么?

到目前为止,似乎我必须做类似的事情:

for coord1 in coordinates:
    for coord2 in coordinates:
        if (not_already_done_(coord1,coord2)):
            dist = math.hypot(coord2.x - coord1.x, coord2.y - coord1.y)
            save_dist(dist,coord1,coord2)

有没有更快的方法?或者至少有更好的方式来写它吗?

4 个答案:

答案 0 :(得分:5)

使用itertools.combinations

from math import hypot
from itertools import combinations

coordinates = [(1, 1), (2, 2), (-2, 5)]

distances = {(a,b): hypot(a[0] - b[0], a[1] - b[1])
             for a, b in combinations(coordinates, 2)}

答案 1 :(得分:2)

怎么样:

for n, coord1 in enumerate(coordinates[:-1]):
    for coord2 in coordinates[n+1:]:
        dist = math.hypot(coord2.x - coord1.x, coord2.y - coord1.y)
        save_dist(dist,coord1,coord2)

或:

for n in range(len(coordinates) - 1):
    coord1 = coordinates[n] 
    for m in range(n+1, len(coordinates)):
        coord2 = coordinates[m]
        dist = math.hypot(coord2.x - coord1.x, coord2.y - coord1.y)
        save_dist(dist,coord1,coord2)

答案 2 :(得分:1)

您还可以在班级中嵌入distance函数,该函数计算坐标与另一个坐标之间的距离。你的课程看起来像这样:

from math import hypot

class Coordinate(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def getX(self):
        return self.x

    def getY(self):
        return self.y

    def distance(self, other):
        dx = self.x - other.x
        dy = self.y - other.y

        return hypot(dx, dy)

然后您可以使用itertools.combinations来获取Coordinate对象之间的坐标距离,正如其他人建议的那样:

coordinates = [Coordinate(1, 2), Coordinate(2, 3), Coordinate(3, 4)]

distances = [[(c1.getX(), c1.getY()), (c2.getX(), c2.getY()), c1.distance(c2)] for c1, c2 in combinations(coordinates, 2)]

print(distances)

哪个输出:

[[(1, 2), (2, 3), 1.4142135623730951], [(1, 2), (3, 4), 2.8284271247461903], [(2, 3), (3, 4), 1.4142135623730951]]

答案 3 :(得分:1)

您可以在多个索引范围内使用列表推导:

from math import hypot

# assume l is a sequence of (x,y) coordinates
distances = [(hypot(l[i][0]-l[j][0],l[i][1]-l[j][1]), l[i], l[j]) for i in range(len(l)) for j in range(i+1, len(l))]

通过将距离计算提取到自己的命名函数中,可以使其更具可读性。