如何计算两个邮编之间的距离?

3
我有一个美国邮政编码列表,需要计算所有邮政编码点之间的距离。这个列表有6000个邮编实体,每个实体都包括邮编、城市、州、纬度、经度、面积和人口。
因此,我需要计算所有点之间的距离,即6000C2组合。
以下是我的数据样例:

enter image description here

我尝试在SAS中实现这个功能,但速度太慢且效率低下,因此我正在寻找使用Python或R的方法。

感谢任何线索。


2
一个选项,也许不是最好的,就是使用Haversine公式和一对ZIP代码的纬度/经度坐标。 - Tim Biegeleisen
@TimBiegeleisen 在参考了一些文章之后,我认为 Haversine 公式可能并不是真正准确的。 - lightyagami96
1
这可能对R有所帮助。重要的是imap包中的gdist函数。更一般地,R中有许多GIS包,毫无疑问涉及计算速度、准确性和易用性等各种优缺点。请参考R中的GIS包 - John Coleman
1
为了更准确,您可以使用基于地球椭球模型的__Vincenty算法__。 - Heaven
我在SAS中尝试了这个...... 你能展示一下你尝试了什么吗?是哪些基准让你确定它很慢和低效?你在哪台工作站或服务器上运行SAS?好奇的是,什么问题要求你首先计算所有距离? - Richard
显示剩余3条评论
3个回答

9

Python解决方案

如果您有邮政编码对应的纬度和经度,您可以使用'mpu'库直接使用Haversine公式计算它们之间的距离,该公式确定了球面上两点之间的大圆距离。

示例代码:

import mpu

zip_00501 =(40.817923,-73.045317)
zip_00544 =(40.788827,-73.039405)

dist =round(mpu.haversine_distance(zip_00501,zip_00544),2)
print(dist)

您将获得以公里为单位的结果距离。 输出:

3.27

提示:如果您没有邮政编码的相应坐标,可以使用“uszipcode”库的“SearchEngine”模块获取相同的信息(仅适用于美国邮政编码)

from uszipcode import SearchEngine
#for extensive list of zipcodes, set simple_zipcode =False
search = SearchEngine(simple_zipcode=True)

zip1 = search.by_zipcode('92708')
lat1 =zip1.lat
long1 =zip1.lng

zip2 =search.by_zipcode('53404')
lat2 =zip2.lat
long2 =zip2.lng

mpu.haversine_distance((lat1,long1),(lat2,long2))

希望这可以帮到您!

嗨,我们尝试了上述解决方案并压缩了这些代码:00501和00544,但是我们遇到了以下错误。[.. \ mpu \ init.py",第193行,在haversine_distance中 如果不是(-90.0 <= lat1 <= 90): TypeError:'<'不支持'float'和'NoneType'的实例之间的操作符。请问我错过了什么? - Santana
嘿,看起来它无法识别其中一个邮政编码。你能否尝试将“simple_zipcode”设置为False?如果不起作用,请告诉我,我会深入研究它。 - jitesh2796
嗨Jitesh,感谢您的回答。我们尝试了这些邮政编码03060和03062。它们在使用'False'或不使用时都很好用,但是当我们使用03060和02222时,相同的错误会出现在False和True中。 - Santana
嗨,Santana,我检查了邮政编码02222。似乎在uszipcode库中没有对应于此邮政编码的纬度和经度。如果您只打印各种变量,如zip1、zip2、lat和long等,您将能够看到可用的信息。我在网上检查了邮政编码并找到了纬度和经度,使用这些值可以正常工作。uszipcode可能没有所有邮政编码的详尽信息,您可以搜索是否有其他库可用。希望这有所帮助... - jitesh2796

4

在SAS中,使用GEODIST函数

GEODIST函数

返回两个纬度和经度坐标之间的地理距离。

语法

GEODIST(纬度1, 经度1, 纬度2, 经度2 , 选项)


注意:保留HTML标记。

2

R解决方案

#sample data: first three rows of data provided
df <- data.frame( zip = c( "00501", "00544", "00601" ),
                  longitude = c( -73.045075, -73.045147, -66.750909 ),
                  latitude = c( 40.816799, 40.817225, 18.181189 ),
                  stringsAsFactors = FALSE )

library( sf ) 

#create a spatial data.frame
spdf <- st_as_sf( x = df, 
                  coords = c( "longitude", "latitude"), 
                  crs = "+proj=longlat +datum=WGS84" )

#create the distance matrix (in meters), round to 0 decimals
m <- round( st_distance( spdf ), digits = 0 )

#set row and column names of matrix
colnames( m ) <- df$zip
rownames( m ) <- df$zip

#show distance matrix in meters
m 

# Units: m
#         00501   00544   00601
# 00501       0      48 2580481
# 00544      48       0 2580528
# 00601 2580481 2580528       0

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