有效计算两个数据集之间的成对半正矢距离 - NumPy / Python

2023-12-13

我想计算经纬度之间的地理距离。

我已经检查过这个线程Python 中向量化半正矢距离计算但是当我将它用于两组不同的坐标时,我收到错误。

df1 的大小可以是数百万,如果有任何其他方法可以在更短的时间内计算准确的地理距离,那么它将非常有帮助。

length1 = 1000
d1 = np.random.uniform(-90, 90, length1)
d2 = np.random.uniform(-180, 180, length1)
length2 = 100
d3 = np.random.uniform(-90, 90, length2)
d4 = np.random.uniform(-180, 180, length2)
coords = tuple(zip(d1, d2))
df1 = pd.DataFrame({'coordinates':coords})
coords = tuple(zip(d3, d4))
df2 = pd.DataFrame({'coordinates':coords})

def get_diff(df1, df2):
    data1 = np.array(df1['coordinates'].tolist())
    data2 = np.array(df2['coordinates'].tolist())
    lat1 = data1[:,0]                     
    lng1 = data1[:,1]
    lat2 = data2[:,0]                     
    lng2 = data2[:,1]
    #print(lat1.shape)
    #print(lng1.shape)
    #print(lat2.shape)
    #print(lng2.shape)
    diff_lat = lat1[:,None] - lat2

    diff_lng = lng1[:,None] - lng2
    #print(diff_lat.shape)
    #print(diff_lng.shape)
    d = np.sin(diff_lat/2)**2 + np.cos(lat1[:,None])*np.cos(lat1) * np.sin(diff_lng/2)**2
    return 2 * 6371 * np.arcsin(np.sqrt(d))

get_diff(df1, df2)
ValueError                                Traceback (most recent call last)
<ipython-input-58-df06c7cff72c> in <module>
----> 1 get_diff(df1, df2)

<ipython-input-57-9bd8f10189e6> in get_diff(df1, df2)
     26     print(diff_lat.shape)
     27     print(diff_lng.shape)
---> 28     d = np.sin(diff_lat/2)**2 + np.cos(lat1[:,None])*np.cos(lat1) * np.sin(diff_lng/2)**2
     29     return 2 * 6371 * np.arcsin(np.sqrt(d))

ValueError: operands could not be broadcast together with shapes (1000,1000) (1000,100) 

成对半正矢距离

这是一种矢量化的方式broadcasting基于this post -

def convert_to_arrays(df1, df2):
    d1 = np.array(df1['coordinates'].tolist())
    d2 = np.array(df2['coordinates'].tolist())
    return d1,d2

def broadcasting_based_lng_lat(data1, data2):
    # data1, data2 are the data arrays with 2 cols and they hold
    # lat., lng. values in those cols respectively
    data1 = np.deg2rad(data1)                     
    data2 = np.deg2rad(data2)                     

    lat1 = data1[:,0]                     
    lng1 = data1[:,1]         

    lat2 = data2[:,0]                     
    lng2 = data2[:,1]         

    diff_lat = lat1[:,None] - lat2
    diff_lng = lng1[:,None] - lng2
    d = np.sin(diff_lat/2)**2 + np.cos(lat1[:,None])*np.cos(lat2) * np.sin(diff_lng/2)**2
    return 2 * 6371 * np.arcsin(np.sqrt(d))

因此,为了解决您的情况以获得所有成对半正弦距离,它将是 -

broadcasting_based_lng_lat(*convert_to_arrays(df1,df2))

元素级半正矢距离

对于两个数据之间的元素级半正弦距离计算,使得每个数据在每列两列或每列两个元素的列表中保存纬度和经度,我们将跳过一些扩展2D最终得到这样的结果 -

def broadcasting_based_lng_lat_elementwise(data1, data2):
    # data1, data2 are the data arrays with 2 cols and they hold
    # lat., lng. values in those cols respectively
    data1 = np.deg2rad(data1)                     
    data2 = np.deg2rad(data2)                     

    lat1 = data1[:,0]                     
    lng1 = data1[:,1]         

    lat2 = data2[:,0]                     
    lng2 = data2[:,1]         

    diff_lat = lat1 - lat2
    diff_lng = lng1 - lng2
    d = np.sin(diff_lat/2)**2 + np.cos(lat1)*np.cos(lat2) * np.sin(diff_lng/2)**2
    return 2 * 6371 * np.arcsin(np.sqrt(d))

使用将两个数据保存在两列中的数据框进行示例运行 -

In [42]: np.random.seed(0)
    ...: a = np.random.randint(10,100,(5,2)).tolist()
    ...: b = np.random.randint(10,100,(5,2)).tolist()
    ...: df = pd.DataFrame({'A':a,'B':b})

In [43]: df
Out[43]: 
          A         B
0  [54, 57]  [80, 98]
1  [74, 77]  [98, 22]
2  [77, 19]  [68, 75]
3  [93, 31]  [49, 97]
4  [46, 97]  [56, 98]

In [44]: from haversine import haversine

In [45]: [haversine(i,j) for (i,j) in zip(df.A,df.B)]
Out[45]: 
[3235.9659882513424,
 2399.6124657290075,
 2012.0851666001824,
 4702.8069773315865,
 1114.1193334220534]

In [46]: broadcasting_based_lng_lat_elementwise(np.vstack(df.A), np.vstack(df.B))
Out[46]: 
array([3235.96151855, 2399.60915125, 2012.08238739, 4702.80048155,
       1114.11779454])

这些细微的差异很大程度上是因为haversine library假设6371.0088作为地球半径,而我们将其视为6371 here.

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

有效计算两个数据集之间的成对半正矢距离 - NumPy / Python 的相关文章

随机推荐

  • 类的字段,它们存储在栈中还是堆中?

    我昨天看到一个问题 它 对我来说 提出了另一个问题 请看下面的代码 public class Class1 int A as I uderstand int is value type and therefore lives in the
  • x 个字符后的 ajax 调用

    我有一个 ajax 调用在输入的最大长度上触发 但是 如果用户继续输入字符 因为它们算作按键 它会继续触发 有什么办法可以防止在 5 个字符限制之后出现额外的 ajax 调用吗 html
  • 如何从 python 启用 Windows 控制台快速编辑模式?

    我想在运行 python 脚本时在控制台中强制使用快速编辑模式 然后在终止之前禁用它 有没有办法做到这一点 对于任何试图仅为当前控制台禁用快速编辑和插入模式并且无法找到简单解决方案的人 import ctypes kernel32 ctyp
  • 在 JS 中不可能用全局变量的名称传递局部变量?

    foo foobar var bar function var foo foo return foo bar 此代码给出结果空字符串 为什么JS不能重新分配与全局变量同名的局部变量 在其他编程语言中 预期结果当然是 foobar 为什么 J
  • 在 python 中使用 Selenium 使用 ng-model 定位元素

    我正在尝试在 python 中使用 Selenium 自动化 AngularJS 应用程序 我正在尝试使用 ng modal 找到一个元素 我看过一些与Java相关的帖子 其中指定您可以使用以下语句 input ng model yourN
  • Discord.js 提取电子邮件

    下面的代码让我可以获取有关不和谐用户的所有信息 但是 我找不到获取用户电子邮件的方法 它已被弃用吗 有人可以帮我解决代码吗 client on ready gt console log logged in as client user us
  • Pip 不适用于 Ubuntu 上的 Python 3.10

    一般来说 我对使用 Ubuntu 和 Linux 很陌生 我只是尝试使用更新Pythonsudo apt get install python3 10 当我跑步时python3 10 m pip install
  • 将视频保存在 iPhone 模拟器中并将其上传到网络服务

    我只是想知道如何将视频保存到 iPhone 模拟器以及如何将其上传到网络服务 谢谢 vpc UIImagePickerController alloc init vpc delegate self vpc sourceType UIImag
  • OpenCV:计算椭圆长轴和短轴的方向角

    我在用cv2 fitEllipse 在轮廓上拟合椭圆 该函数返回中心坐标 长轴和短轴以及旋转角度 我想知道旋转角度是否与此处给出的长轴与正水平轴的角度相同 src 维基百科 如果没有 那么有什么方法可以得到下面等式中椭圆的系数 然后直接计算
  • 检索MySQL中每个record_id的每列的最后一个非空记录

    我有这个 MySQL 表名为records 以下是其内容 id record id Data1 Data2 Time 1 1 null 1 1 1 16 2 1 1 null 1 3 16 3 1 2 null 1 4 16 4 1 nul
  • 如何在 JavaScript 中解压缩 gzip 文件?

    我已经得到了ArrayBuffer数据 如下称为 s 由许多块组成 从我们的服务端生成 blob 生成如下 var blob new Blob s slice 4 82838 但我制作的 blob 是 gzip 数据 如何在 javascr
  • 在 Android 手机上部署应用程序时找不到 java.time.LocalDateTime 类 [重复]

    这个问题在这里已经有答案了 当我在 Android 手机上部署 Android 应用程序时 我遇到了 ClassNotFoundException 我在 Android 6 0 1 和 Android 7 1 1 的 Android 手机上
  • 执行 xp_cmdshell bcp 语法

    我似乎找不到正确的语法来使用 sql server management studio 中的 exec xp cmdshell bcp 导出具有列名称的数据 我尝试了以下变体 EXEC xp cmdshell bcp select a id
  • CSS,更改链接中图标字体的悬停效果

    我有一个像这样的导航元素 ul class options list li a href i class icon icon print i Print This a li li a href i class icon icon envel
  • 将当前时间放入标签中

    我正在尝试使用日期获取日期和时间 但是当我运行应用程序时 它需要第一次执行应用程序时间 并且短时间内的日期不会改变 NSDate StrDate NSDate date NSDateFormatter Dateformat NSDateFo
  • javax.validation.constraints.Pattern 注释的参数化错误消息?

    我有一个具有类型字段的实体String我在其上定义了一个 Pattern注释强制执行与给定正则表达式匹配的字段内容 现在我想知道是否可以参数化约束 例如在定义的验证错误消息中显示与正则表达式不匹配的第一个字符 更糟糕的是 违反约束时显示的错
  • 在 C 中使用 pow() 函数会引发未定义的引用错误

    为什么下面的代码在 C 中可以工作 int res pow 2 3 printf d n res 而另一个则没有 int a 2 int b 3 int res pow a b printf d n res 即使我尝试 double a 2
  • onSaveInstanceState() 和 onRestoreInstanceState()

    我正在尝试保存并恢复状态Activity使用方法onSaveInstanceState and onRestoreInstanceState 问题是它永远不会进入onRestoreInstanceState 方法 谁能向我解释这是为什么 通
  • Android 自定义相机变焦不起作用

    我看过关于这个主题的其他几个问题 但似乎没有一个能解决我的问题 我有一个自定义相机应用程序 除了变焦按钮之外 一切都工作正常 这是我使用 SDK min 8 target 14 的代码 Override public void surfac
  • 有效计算两个数据集之间的成对半正矢距离 - NumPy / Python

    我想计算经纬度之间的地理距离 我已经检查过这个线程Python 中向量化半正矢距离计算但是当我将它用于两组不同的坐标时 我收到错误 df1 的大小可以是数百万 如果有任何其他方法可以在更短的时间内计算准确的地理距离 那么它将非常有帮助 le