【问题标题】:How to calculate distance between n coordinates in python如何计算python中n坐标之间的距离
【发布时间】:2020-05-03 13:34:33
【问题描述】:

我正在处理一个python 项目,我从一个函数中获取x, ydict 中的坐标值,如下所示:

centroid_dict = {0: (333, 125), 1: (288, 52), 2: (351, 41)}

其中0, 1, 2objectId(333, 125), (288, 52), (351, 41) 分别是它们的(x, y) 坐标值。我需要计算每个坐标之间的距离,这意味着:

0 - 1 -> ((333, 125) - (288, 52))

0 - 2 -> ((333, 125) - (351, 41))

1 - 0 -> ((288, 52) - (333, 125))

1 - 2 -> ((288, 52) - (351, 41))

2 - 0 -> ((351, 41) - (333, 125))

2 - 1 -> ((351, 41) - (288, 52))

要计算距离,我可以使用:

def calculateDistance(x1, y1, x2, y2):
    dist = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
    return dist

但是我想不出任何可以计算每个点之间距离的逻辑,因为 dict 的长度将来可能会增加。截至目前,它是3,但也可以是10。任何人都可以帮我提供一些想法。谢谢

【问题讨论】:

标签: python coordinates distance


【解决方案1】:

您可以使用来自 itertools 的组合来形成一个以每对对象为键的新字典:

from itertools import combinations:
distances = dict()
for (id1,p1),(id2,p2) in combinations(centroid_dict.items(),2):
    dx,dy = p1[0]-p2[0], p1[1]-p2[1]
    distances[id1,id2] = distances[id2,id1] = math.sqrt(dx*dx+dy*dy)

这种方法的缺点是它会系统地计算所有距离,您的程序可能不需要访问所有这些值。一种更有效的方法是使用字典作为距离缓存,并使用函数“按需”获取它们:

distanceCache = dict()
def getDist(id1,id2):
    if id1 > id2: return getDist(id2,id1) # only store each pair once
    if (id1,id1) in distanceCache: return distanceCache[id1,id2]
    x1,y1 = centroid_dict[id1]
    x2,y2 = centroid_dict[id2]
    dx,dy = x1-x2,y1-y2 
    return distanceCache.setDefault((id1,id2),math.sqrt(dx*dx+dy*dy))

这将允许您在对象位置更改时简单地清除缓存,而不会立即延迟 O(n^2) 时间

请注意,您也可以使用点(位置)本身作为缓存的键,也可以使用 LRU 缓存(来自 functools)

from functools import lru_cache
import math

@lru_cache(1024)
def getDist(p1,p2):
    dx,dy = p1[0]-p2[0],p1[1]-p2[1]
    return math.sqrt(dx*dx+dy*dy)

def getObjectDist(id1,id2):
    return getDist(centroid_dict[id1],centroid_dict[id2])

【讨论】:

  • 在你的第一个例子中,我无法理解这一行 distances[id1,id2] = distances[id2,id1] = math.sqrt(dx*dx+dy*dy) 你能解释一下这里发生了什么吗?
  • 按两个顺序为一对对象 id(元组)分配距离字典。 (即 (id1,id2) 和 (id2 ,id1)),因为无论哪个是起点,哪个是目的地,它的距离都是相同的。这将允许每对仅计算一次距离,同时提供对距离的访问,而无需使用对象 ID 的特定顺序。
【解决方案2】:

使用here的解决方案,它是k d tree graph problem

求四个二维坐标之间的欧几里得距离:

from scipy.spatial import distance
coords = [(35.0456, -85.2672),
          (35.1174, -89.9711),
          (35.9728, -83.9422),
          (36.1667, -86.7833)]
distance.cdist(coords, coords, 'euclidean')

array([[ 0.    ,  4.7044,  1.6172,  1.8856],
   [ 4.7044,  0.    ,  6.0893,  3.3561],
   [ 1.6172,  6.0893,  0.    ,  2.8477],
   [ 1.8856,  3.3561,  2.8477,  0.    ]])

【讨论】:

    【解决方案3】:

    你可以做这样的事情。无需导入。

    def dist(key1,key2):
        return calculateDistance(*centroid_dict[key1],*centroid_dict[key2])
    
    all_dist = []
    for key1 in centroid_dict:
        all_dist.extend([dist(key1,key2) for key2 in centroid_dict if not key1==key2])
    

    【讨论】:

      猜你喜欢
      • 2021-09-08
      • 1970-01-01
      • 2020-06-02
      • 2021-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多