如何在Python中遍历坐标列表并计算它们之间的距离

8

我有一个包含20个坐标(x和y坐标)的列表。我可以计算任意两个坐标之间的距离,但是我很难编写一个算法来遍历该列表并计算第一个节点与其他所有节点之间的距离。例如:

ListOfCoordinates = [(1,2), (3,4), (5,6), (7,8), (9,10), (11,12)]

在这种情况下,我需要一个for循环来遍历列表并计算第一个坐标和第二个坐标之间的距离,第一个坐标和第三个坐标之间的距离等等。我需要一个算法来帮助我,然后我将把它转换成Python代码。谢谢。
感谢所有反馈,这对我很有帮助。

这很基础 - 一个循环嵌套在另一个里面。有什么难的? - Filipe Gonçalves
@frostnational 这个解决方案很差,因为它每次都会复制列表并删除当前项,增加运行时间。 - Eyrofire
4个回答

10

每当您需要处理组合问题(例如“我需要首先和第二个,然后是第一和第三个,然后...”)时,itertools 模块通常都会有您需要的工具。

from math import hypot

def distance(p1,p2):
    """Euclidean distance between two points."""
    x1,y1 = p1
    x2,y2 = p2
    return hypot(x2 - x1, y2 - y1)

from itertools import combinations

list_of_coords = [(1,2), (3,4), (5,6), (7,8), (9,10), (11,12)]

[distance(*combo) for combo in combinations(list_of_coords,2)]
Out[29]: 
[2.8284271247461903,
 5.656854249492381,
 8.48528137423857,
 11.313708498984761,
 14.142135623730951,
 2.8284271247461903,
 5.656854249492381,
 8.48528137423857,
 11.313708498984761,
 2.8284271247461903,
 5.656854249492381,
 8.48528137423857,
 2.8284271247461903,
 5.656854249492381,
 2.8284271247461903]

编辑:你的问题有点令人困惑。以防万一,如果您只想将第一个观点与其他观点进行比较:

from itertools import repeat

pts = [(1,2), (3,4), (5,6), (7,8), (9,10), (11,12)]

[distance(*pair) for pair in zip(repeat(pts[0]),pts[1:])]
Out[32]: 
[2.8284271247461903,
 5.656854249492381,
 8.48528137423857,
 11.313708498984761,
 14.142135623730951]

但是通常在这种问题中,您关心所有组合,因此我将保留第一个答案。


1
这是最正确的解决方案。从原始列表的副本中删除当前项的方法会使大型数据集的运行时间膨胀。 - Eyrofire
感谢你指引我使用 itertools(以及其中的 operator)。这是一个强大而实用的工具! - kratenko

1

我想要一个单行脚本来实现这个。以下脚本为我完成了这项工作。

import numpy as np
yd = [(1,2), (3,4), (5,6), (7,8), (9,10), (11,12)]
distances_matrix = np.array([np.linalg.norm((item*np.ones((len(yd),len(item))))-yd,axis=1) for item in yd])

print(distances_matrix)

output:
[[ 0.          2.82842712  5.65685425  8.48528137 11.3137085  14.14213562]
 [ 2.82842712  0.          2.82842712  5.65685425  8.48528137 11.3137085 ]
 [ 5.65685425  2.82842712  0.          2.82842712  5.65685425  8.48528137]
 [ 8.48528137  5.65685425  2.82842712  0.          2.82842712  5.65685425]
 [11.3137085   8.48528137  5.65685425  2.82842712  0.          2.82842712]
 [14.14213562 11.3137085   8.48528137  5.65685425  2.82842712  0.        ]]


#Distance between coordinates with indices 2 and 4
print(distance_matrix[2,4])
output:
5.656854249492381


注意:这里我只使用Numpy计算欧几里得距离。这个解决方案适用于大多数情况。但是当数组/列表太大且在内存中复制不可行时,不建议使用此方法。

1
不需要任何计算,我可以说从 1, 23, 4 的距离明显小于 20 - Klaus D.
感谢 Klaus D 指出错误,我已经更正了。 - tachyontraveler

0
In [6]: l = [(1,2), (3,4), (5,6), (7,8), (9,10), (11,12)]

In [7]: def distance(a, b):                              
    return (a[0] - b[0], a[1] - b[1])
   ...: 

In [8]: for m in l[1:]:                                  
    print(distance(l[0], m))
   ...:     
(-2, -2)
(-4, -4)
(-6, -6)
(-8, -8)
(-10, -10)

当然,您需要根据自己的需求来适应distance


0
你可以创建一个名为 distance 的函数,该函数接受两个元组作为参数,这两个元组是坐标对。
def distance(p1, p2):
    return math.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)

由于您只需要一个算法来计算第一个节点和其他每个节点之间的距离,请创建一个循环,循环遍历您的ListOfCoordinates

for i in range(1, len(ListOfCoordinates)):
    # you can use print or return, depending on your needs
    print distance(ListOfCoordinates[0], ListOfCoordinates[i])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接