如何在Python中遍历坐标列表并计算它们之间的距离
我有一个包含20个坐标的列表(每个坐标有x和y两个值)。我可以计算任意两个坐标之间的距离,但我在写一个算法时遇到了困难,这个算法需要遍历整个列表,计算第一个坐标和其他每个坐标之间的距离。例如,
ListOfCoordinates = [(1,2), (3,4), (5,6), (7,8), (9,10), (11,12)]
在这个情况下,我需要一个for循环来遍历这个列表,计算第一个坐标和第二个坐标之间的距离,第一个坐标和第三个坐标之间的距离,依此类推。我需要一个算法来帮助我,然后我会把它转成Python代码。谢谢!
感谢大家的反馈,这对我很有帮助。
4 个回答
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])
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
。
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计算的欧几里得距离。这种方法在大多数情况下都能用。但如果数组或列表太大,复制一份到内存中就不太合适了。
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]
但通常在这种类型的问题中,你会关心所有的组合,所以我会把第一个答案保留在这里。