Scipy:如何将KD-Tree距离从查询转换为公里(Python/Pandas) [英] Scipy: how to convert KD-Tree distance from query to kilometers (Python/Pandas)

查看:153
本文介绍了Scipy:如何将KD-Tree距离从查询转换为公里(Python/Pandas)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这篇文章基于此一个.

我得到了一个Pandas数据框,其中包含城市的地理坐标(大地)为经度和纬度.

I got a Pandas dataframe containing cities with their geo-coordinates (geodetic) as longitude and latitude.

import pandas as pd

df = pd.DataFrame([{'city':"Berlin", 'lat':52.5243700, 'lng':13.4105300},
                   {'city':"Potsdam", 'lat':52.3988600, 'lng':13.0656600},
                   {'city':"Hamburg", 'lat':53.5753200, 'lng':10.0153400}]);

对于每个城市,我都试图找到其他两个最接近的城市.因此,我尝试了scipy.spatial.KDTree.为此,我必须将大地坐标转换为3D直角坐标(ECEF =以地球为中心,固定在地球上):

For each city I'm trying to find two other cities that are closest. Therefore I tried the scipy.spatial.KDTree. To do so, I had to convert the geodetic coordinates into 3D catesian coordinates (ECEF = earth-centered, earth-fixed):

from math import *

def to_Cartesian(lat, lng):
    R = 6367 # radius of the Earth in kilometers

    x = R * cos(lat) * cos(lng)
    y = R * cos(lat) * sin(lng)
    z = R * sin(lat)
    return x, y, z

df['x'], df['y'], df['z'] = zip(*map(to_Cartesian, df['lat'], df['lng']))
df

这给我这个:

以此我可以创建KDTree:

With this I can create the KDTree:

coordinates = list(zip(df['x'], df['y'], df['z']))

from scipy import spatial
tree = spatial.KDTree(coordinates)
tree.data

现在我要在柏林进行测试,

Now I'm testing it with Berlin,

tree.query(coordinates[0], 2)

正确地使我(自己)和波茨坦成为我列表中与柏林最接近的两个城市.

which correctly gives me Berlin (itself) and Potsdam as the two cities from my list that are closest to Berlin.

问题:但是我想知道该查询的距离如何处理?上面写着1501-但是我如何将其转换为米或公里?柏林到波茨坦的真实距离是27公里,而不是1501公里.

Question: But I wonder what to do with the distance from that query? It says 1501 - but how can I convert this to meters or kilometers? The real distance between Berlin and Potsdam is 27km and not 1501km.

备注::我知道我可以同时获得两个城市的经度/纬度,并计算其正弦距离.但是使用KDTree的输出代替是很酷的.

Remark: I know I could get longitude/latitude for both cities and calculate the haversine-distance. But would be cool that use the output from KDTree instead.

(array([0.,1501.59637685]),array([0,1]))

(array([ 0. , 1501.59637685]), array([0, 1]))

感谢您的帮助.

推荐答案

KDTree正在计算两个点(城市)之间的欧式距离.这两个城市和地球中心形成一个等腰三角形.

The KDTree is computing the euclidean distance between the two points (cities). The two cities and the center of the earth form an isosceles triangle.

德语Wikipedia条目包含几何属性的漂亮概述.缺少入口.您可以使用它来计算距离.

The German wikipedia entry contains a nice overview of the geometric properties which the English entry lacks. You can use this to compute the distance.

import numpy as np

def deg2rad(degree):
    rad = degree * 2*np.pi / 360
    return(rad)

def distToKM(x):
    R = 6367 # earth radius
    gamma = 2*np.arcsin(deg2rad(x/(2*R))) # compute the angle of the isosceles triangle
    dist = 2*R*sin(gamma/2) # compute the side of the triangle
    return(dist)

distToKM(1501.59637685)
# 26.207800812050056


更新

在发表评论后,我重新阅读了问题,并意识到,虽然似乎可以使用上面建议的功能,但真正的问题出在其他地方.


Update

After the comment about obtaining the opposite I re-read the question and realised that while it seems that one can use the proposed function above, the real problem lies somewhere else.

cossin期望输入位于radians中(

cos and sin in your function to_Cartesian expect the input to be in radians (documentation) whereas you are handing them the angles in degree. You can use the function deg2rad defined above to transform the latitude and longitude to radians. This should give you the distance in km directly from the KDTree.

这篇关于Scipy:如何将KD-Tree距离从查询转换为公里(Python/Pandas)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆