Python 计算两个列表上的haversine

Python 计算两个列表上的haversine,python,pandas,geopandas,Python,Pandas,Geopandas,我目前正在尝试计算Geopandas数据帧中的(纬度/长)坐标的路线距离。我对这个包很陌生,但基本上我有几个点组成了一条路线,我所要做的就是找到路线的实际总距离。我可以通过两个固定点来实现这一点,这是我欠用户@steve clark的帮助: # Start lon1 = 41.592181 lat1 = -87.638856 # End lat2 = -86.754688 lon2 = 41.877575 def haversine(lat1, lon1, lat2, lon2): "

我目前正在尝试计算Geopandas数据帧中的(纬度/长)坐标的路线距离。我对这个包很陌生,但基本上我有几个点组成了一条路线,我所要做的就是找到路线的实际总距离。我可以通过两个固定点来实现这一点,这是我欠用户@steve clark的帮助:

# Start
lon1 = 41.592181
lat1 = -87.638856
# End
lat2 = -86.754688
lon2 = 41.877575

def haversine(lat1, lon1, lat2, lon2):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a))
    r = 6371 # Radius of earth in kilometers
    print('Distance from beginning to end of route in km: ',round((c * r), 2),'\n')
我被两件事困住了,我目前正在四处搜寻,看看我是否可以计算出距Geopandas
point()
对象的距离,但老实说,我找到的示例要么与我的问题无关,要么超出了我的理解范围(此时)

我能够将纬度和经度列从我的gpd中拉入列表,但我无法在循环中应用它

LatList = geo_data['latitude'].tolist()
LonList = geo_data['longitude'].tolist()
我尝试将我迭代的内容附加到一个新列表中,并对距离求和,但最终得到一个附加了2850次相同值的列表。感谢任何帮助或指导

编辑:根据请求,这是失败的代码

distance = []

    for i, j in zip(LatList, LonList):

        dlat = i - i+1
        dlon = j - j+1

        a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
        c = 2 * asin(sqrt(a))
        r = 6371 # Radius of earth in kilometers

        distance.append(round((c * r), 2))

    print(distance)

您需要调整
i
i+1
j
j+1
的定义,否则循环将无法执行您希望的操作

distance = []

LatLonList = list(zip(LatList, LonList))

    # notice that if you do "for n in len(LatLonList)", the loop will fail in the last element
    for n in len(LatLonList) -1:

        dlat = LatLonList[n][0] - LatLonList[n+1][0]  # this is for i
        dlon = LatLonList[n][1] - LatLonList[n+1][1]  # this is for j

        a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
        c = 2 * asin(sqrt(a))
        r = 6371 # Radius of earth in kilometers

        distance.append(round((c * r), 2))

    print(distance)

您需要调整
i
i+1
j
j+1
的定义,否则循环将无法执行您希望的操作

distance = []

LatLonList = list(zip(LatList, LonList))

    # notice that if you do "for n in len(LatLonList)", the loop will fail in the last element
    for n in len(LatLonList) -1:

        dlat = LatLonList[n][0] - LatLonList[n+1][0]  # this is for i
        dlon = LatLonList[n][1] - LatLonList[n+1][1]  # this is for j

        a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
        c = 2 * asin(sqrt(a))
        r = 6371 # Radius of earth in kilometers

        distance.append(round((c * r), 2))

    print(distance)

以geopandas参考中的数据为例:

将熊猫作为pd导入
进口土工画板
从shapely.geometry导入点
df=pd.DataFrame(
{‘城市’:[‘布宜诺斯艾利斯’、‘巴西利亚’、‘圣地亚哥’、‘波哥大’、‘加拉加斯’],
“国家”:[“阿根廷”、“巴西”、“智利”、“哥伦比亚”、“委内瑞拉”],
“纬度”:[-34.58,--15.78,--33.45,4.60,10.48],
‘经度’:[-58.66,-47.91,-70.66,-74.08,-66.86])
df['Coordinates']=列表(zip(df.经度,df.纬度))
df['Coordinates']=df['Coordinates'].应用(点)
gdf=geopandas.GeoDataFrame(df,geometry='Coordinates')
使用两点作为输入的距离可写为:

def haversine(第1点、第2点): """ 计算两点之间的大圆距离 地球上(以十进制度数表示) """ lon1,lat1=point1.bounds[0],point1.bounds[1] lon2,lat2=point2.bounds[0],point2.bounds[1] #将十进制度数转换为弧度 lon1,lat1,lon2,lat2=贴图(弧度,[lon1,lat1,lon2,lat2]) #哈弗森公式 dlon=lon2-lon1 dlat=lat2-lat1 a=sin(dlat/2)**2+cos(lat1)*cos(lat2)*sin(dlon/2)**2 c=2*asin(sqrt(a)) r=6371#地球半径,单位为公里 #打印('路线起点到终点的距离,单位为km:',圆形((c*r),2),'\n') 返回c*r 并使用
pandas.DataFrame.apply
进行计算:

gdf['Coordinates'].apply(λx:gdf['Coordinates'].apply(λy:haversine(x,y)))
编辑: 只计算矩阵的一半

gdf[['Coordinates'].apply(λx:gdf.loc[:x.name,'Coordinates']).apply(λy:haversine(x['Coordinates'],y)),轴=1)

以geopandas reference中的数据为例:

将熊猫作为pd导入
进口土工画板
从shapely.geometry导入点
df=pd.DataFrame(
{‘城市’:[‘布宜诺斯艾利斯’、‘巴西利亚’、‘圣地亚哥’、‘波哥大’、‘加拉加斯’],
“国家”:[“阿根廷”、“巴西”、“智利”、“哥伦比亚”、“委内瑞拉”],
“纬度”:[-34.58,--15.78,--33.45,4.60,10.48],
‘经度’:[-58.66,-47.91,-70.66,-74.08,-66.86])
df['Coordinates']=列表(zip(df.经度,df.纬度))
df['Coordinates']=df['Coordinates'].应用(点)
gdf=geopandas.GeoDataFrame(df,geometry='Coordinates')
使用两点作为输入的距离可写为:

def haversine(第1点、第2点): """ 计算两点之间的大圆距离 地球上(以十进制度数表示) """ lon1,lat1=point1.bounds[0],point1.bounds[1] lon2,lat2=point2.bounds[0],point2.bounds[1] #将十进制度数转换为弧度 lon1,lat1,lon2,lat2=贴图(弧度,[lon1,lat1,lon2,lat2]) #哈弗森公式 dlon=lon2-lon1 dlat=lat2-lat1 a=sin(dlat/2)**2+cos(lat1)*cos(lat2)*sin(dlon/2)**2 c=2*asin(sqrt(a)) r=6371#地球半径,单位为公里 #打印('路线起点到终点的距离,单位为km:',圆形((c*r),2),'\n') 返回c*r 并使用
pandas.DataFrame.apply
进行计算:

gdf['Coordinates'].apply(λx:gdf['Coordinates'].apply(λy:haversine(x,y)))
编辑: 只计算矩阵的一半

gdf[['Coordinates'].apply(λx:gdf.loc[:x.name,'Coordinates']).apply(λy:haversine(x['Coordinates'],y)),轴=1)
从中找到此代码

从中找到此代码


一个好主意是,在你的问题中加入无法按预期工作的代码。很可能是您的代码中的一个输入错误或类似的琐碎内容导致脚本无法提供您想要的内容。@Claudio添加了它!一个好主意是,在你的问题中加入无法按预期工作的代码。很可能是您的代码中的一个输入错误或类似的琐碎内容导致脚本无法提供您想要的内容。@Claudio添加了它
LatLonList=zip(LatList,LonList)
,没有Len(),因为它是一个生成器,我已经尝试在zip中为n(LatList,LonList)更改回
这使我回到了固定的正方形,
pre_LatLonList=map(lambda x,y:(x,y),LatList,LonList)
LatLonList=list(pre_LatLonList)
你说得对,那部分需要修复,我很高兴你喜欢解决方案。不过有一个更简单的解决方案:
list(zip(…)
LatLonList=zip(LatList,LonList)
,没有Len(),因为它是一个生成器,我已经尝试将zip中的n(LatList,LonList)改回
,这让我回到了t