在Python中计算给定纬度和经度数据的距离矩阵的有效方法

2024-01-22

我有纬度和经度的数据,我需要计算两个包含位置的数组之间的距离矩阵。我用过这个This https://stackoverflow.com/questions/120283/working-with-latitude-longitude-values-in-java/123305#123305获取给定纬度和经度的两个位置之间的距离。

这是我的代码的示例:

import numpy as np
import math

def get_distances(locs_1, locs_2):
    n_rows_1 = locs_1.shape[0]
    n_rows_2 = locs_2.shape[0]
    dists = np.empty((n_rows_1, n_rows_2))
    # The loops here are inefficient
    for i in xrange(n_rows_1):
        for j in xrange(n_rows_2):
            dists[i, j] = get_distance_from_lat_long(locs_1[i], locs_2[j])
    return dists


def get_distance_from_lat_long(loc_1, loc_2):

    earth_radius = 3958.75

    lat_dif = math.radians(loc_1[0] - loc_2[0])
    long_dif = math.radians(loc_1[1] - loc_2[1])
    sin_d_lat = math.sin(lat_dif / 2)
    sin_d_long = math.sin(long_dif / 2)
    step_1 = (sin_d_lat ** 2) + (sin_d_long ** 2) * math.cos(math.radians(loc_1[0])) * math.cos(math.radians(loc_2[0])) 
    step_2 = 2 * math.atan2(math.sqrt(step_1), math.sqrt(1-step_1))
    dist = step_2 * earth_radius

    return dist

我的预期输出是这样的:

>>> locations_1 = np.array([[34, -81], [32, -87], [35, -83]])
>>> locations_2 = np.array([[33, -84], [39, -81], [40, -88], [30, -80]])
>>> get_distances(locations_1, locations_2)
array([[ 186.13522573,  345.46610882,  566.23466349,  282.51056676],
       [ 187.96657622,  589.43369894,  555.55312473,  436.88855214],
       [ 149.5853537 ,  297.56950329,  440.81203371,  387.12153747]])

性能对我来说很重要,我能做的一件事就是使用Cython加快循环速度,但如果我不必去那里就好了。

有没有一个模块可以做这样的事情?或者还有其他解决方案吗?


您使用的半正矢方程中有很多次优的东西。您可以修剪其中的一部分,并最大限度地减少需要计算的正弦、余弦和平方根的数量。以下是我能想到的最好的,在我的系统上,在 1000 和 2000 个元素的两个随机数组上,它的运行速度比 Ophion 的代码(就矢量化而言基本相同)快 5 倍:

def spherical_dist(pos1, pos2, r=3958.75):
    pos1 = pos1 * np.pi / 180
    pos2 = pos2 * np.pi / 180
    cos_lat1 = np.cos(pos1[..., 0])
    cos_lat2 = np.cos(pos2[..., 0])
    cos_lat_d = np.cos(pos1[..., 0] - pos2[..., 0])
    cos_lon_d = np.cos(pos1[..., 1] - pos2[..., 1])
    return r * np.arccos(cos_lat_d - cos_lat1 * cos_lat2 * (1 - cos_lon_d))

如果你“按原样”向它提供两个数组,它会抱怨,但这不是一个错误,而是一个功能。基本上,该函数计算球体在最后一个维度上的距离,并在其余维度上广播。所以你可以获得你想要的东西:

>>> spherical_dist(locations_1[:, None], locations_2)
array([[ 186.13522573,  345.46610882,  566.23466349,  282.51056676],
       [ 187.96657622,  589.43369894,  555.55312473,  436.88855214],
       [ 149.5853537 ,  297.56950329,  440.81203371,  387.12153747]])

但它也可以用于计算两个点列表之间的距离,即:

>>> spherical_dist(locations_1, locations_2[:-1])
array([ 186.13522573,  589.43369894,  440.81203371])

或者在两个单点之间:

>>> spherical_dist(locations_1[0], locations_2[0])
186.1352257300577

这受到了 gufunc 工作方式的启发,一旦你习惯了它,我发现它是一种美妙的“瑞士军刀”编码风格,它可以让你在许多不同的设置中重用单个函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在Python中计算给定纬度和经度数据的距离矩阵的有效方法 的相关文章

随机推荐

  • 单元测试cherpy web应用程序

    我最近不得不重写我们的 REST API 并从 Flask 切换到 Cherrypy 主要是由于 Python 3 兼容性 但现在我一直在尝试编写单元测试 Flask 有一个非常漂亮的内置测试客户端 您可以使用它向您的应用程序发送虚假请求
  • 未将对象引用设置为对象的实例 #5

    sUsername Trim sPassword Trim string ConnectionString WebConfigurationManager ConnectionStrings dbnameConnectionString C
  • 如何编写Delphi编译时函数

    Delphi 我可以自己写吗compile time functions对于 const 和 var 声明 在编译时可执行 标准 Delphi 库包含 Ord Chr Trunc Round High 等例程 用于常量初始化 我可以编写自己
  • 如何获取 Android 应用程序的 Google Places API 密钥

    在过去的 48 小时里 我绞尽脑汁试图找到这个问题的答案 问这个问题的人 如何为 Google Places api 制作 API KEY https stackoverflow com questions 23128152 how can
  • 通知的 PendingIntent 不要第二次调用我的活动

    我希望接收推送通知 c2dm 接收显示Notification 此通知以 PendingIntent 启动 这是一个显示弹出窗口的活动 单击 确定 按钮时 此弹出窗口将启动我的应用程序 这是在接收推送通知时执行的代码 private voi
  • Groovy list.sort 按第一个、第二个然后第三个元素

    我有一个很棒的列表 即 list 2 0 1 1 5 2 1 0 3 我想按第一个元素的顺序对其进行排序 然后是第二个元素 然后是第三个元素 Expected assert list 1 0 3 1 5 2 2 0 1 我开始于list l
  • gem 安装 memcached 失败

    关于做 gem install memcached 抛出以下错误 checking for pod2man usr bin pod2man configure line 22468 syntax error near unexpected
  • 转向 SVG 图标 - 如何将它们与代码分开?

    与字体图标相比 SVG 图标具有一些优势 它们可以缩放以适应可变大小的容器元素 并且理论上您可以更改各个路径的颜色 我还喜欢这样一个事实 我可以轻松地在 Inkscape 中制作它们 P 但是 如何在 CSS 文件中移动 SVG 以便可以在
  • 防止 go build 覆盖 go.mod 中的版本

    我有一个导入项目 foo 的 go 模块 foo 的最新标签显示 v1 4 当我做一个go build在我的项目中 它更新了 go mod 来表示 module github com myid mymod require github co
  • JasperReports 中的 PAGE_COUNT 未正确呈现...?

    我已经添加了页脚第 x 页 共 y 页 我的报告 但 PAGE COUNT 似乎不起作用 也许出现这个问题是因为我有很多子报表 I get Page 1 of 1 Page 2 of 0 Page 3 of 0 Page 4 of 0 有任
  • MySQL:两个时间戳之间的差异(以秒为单位)?

    是否可以计算MySQL中两个时间戳之间的差异并以秒为单位获得输出结果 Like 2010 11 29 13 16 55 2010 11 29 13 13 55应该给 180 秒 谢谢 我不认为接受的答案是一个好的通用解决方案 这是因为 UN
  • javascript中的尾部函数[重复]

    这个问题在这里已经有答案了 我想创建一个添加参数的函数 调用这个函数应该是 functionAdd 2 3 4 n 结果 2 3 4 n 我正在尝试这个 function myfunction num var summ num if num
  • 如何将代码从旧版本的xcode转移到最新版本?

    我有一个xcode我不久前制作的一个应用程序的项目 但它已经启动xcode 3 2 如何轻松地将项目转移到较新版本的xcode 我尝试手动将项目的每个文件传输到新版本 但不是很成功 有没有更简单 更自动化的方法来做到这一点 编辑 从 xco
  • 为什么函数 apply 会抱怨长列表?

    作为一些欧拉阵痛 http projecteuler net 我正在尝试编写一个埃拉托斯特尼筛法 https en wikipedia org wiki Sieve of Eratosthenes带有因式分解轮 到目前为止我的代码是 def
  • 如何从 Java servlet Web 容器正确实现 RabbitMQ RPC?

    我希望传入的 Java servlet Web 请求使用 RPC 方法调用 RabbitMQ 如上所述here http www rabbitmq com tutorials tutorial six java html 但是 我不确定如何
  • 使用 javascript/html 控制 iframe 内容

    在我的网页中 我有一个像这样的 iframe iframe 是同一网站上的页面 我的问题是 是否可以在具有 iframe 的页面上使用 javascript 来控制 thispage html 例如使用 javascript 函数 是的你可
  • 在 Meteor 移动应用程序 (cordova) 上登录 Facebook?

    我正在寻找使用 Meteor Cordova 构建移动应用程序 首先希望 Facebook 登录能够正常工作 显然默认的 account facebook 包不起作用 所以我环顾了一下气氛 只找到了 article4dev cordova
  • AWS代码构建列出其他帐户的s3存储桶

    I have my codebuild build sitting on Account A and s3 buckets on Account B I tried to set up a trusted IAM STS role on A
  • 如何将命令绑定到本地事件?

    我有一个应该捕获 KeyDown KeyUp 事件的表单 此代码在 NRE 中失败 因为它在我当前的视图上查找 KeyDown 控件 this BindCommand ViewModel vm gt vm KeyDown KeyDown 我
  • 在Python中计算给定纬度和经度数据的距离矩阵的有效方法

    我有纬度和经度的数据 我需要计算两个包含位置的数组之间的距离矩阵 我用过这个This https stackoverflow com questions 120283 working with latitude longitude valu