比较两个pandas数据帧之间的地理位置

时间:2016-08-18 19:18:40

标签: pandas dataframe geohashing

我有2个数据帧df1和df2,它们具有不同的Latitutde和经度以及相应的地理位置。现在对于df1中的每个geohash,我想在数据帧df2中找到最接近的geohash。我不确定是否有办法比较地理位置。例如,对于df1中的id 121,df2中最接近的geohash为9muc3rr,d​​f2中的id为122,最接近的geohash为9wv97m1。

Dataframe df1

Id    Latitude   Longitude  Geohash 
121   32.815130 -117.151695  9mudwju
122   37.920948 -108.005043  9wepwr3

Dataframe df2

Id   Latitude    Longitude  Geohash

124  32.604187  -117.005745  9muc3rr
127  37.920948  -108.005043  9wv97m1
135  39.70122   -104.876976  9xj3v7q
128  38.844032  -104.718307  9wvscp6

1 个答案:

答案 0 :(得分:0)

如果您可以稍微重新发明轮子,可以将(lat,lon)对转换为笛卡尔单位向量,然后只使用点积进行比较。由于点积基本上是一个向量投影到另一个向量的度量,因此最接近1(最大值)的乘积将是两个向量之间的最佳匹配。

以下示例计算基于this answer。我将假设您在WGS84椭圆体上提供大地坐标(因为GPS使用的是这样),并且椭圆体上方的高度对于所有点都是零:

from math import radians, sin, cos
import numpy as np

# WGS 84 parameters. Any other ellipsoid can be plugged in by changing
# the following lines. All parameters are taken from Wikipedia at
# https://en.wikipedia.org/wiki/Geodetic_datum#Parameters_for_some_geodetic_systems
invFlat = 298.257222101  # Inverse flattening (1/f), unitless
# Derived parameters
e2 = 6694.37999014  # First eccentricity squared. Unitless. Can be computed from 2*f − f**2

# Note that the radius is irrelevant since we are going to
# normalize the result anyway.

def cartesianUnitVector(lat, lon, isdeg=True):
    if isdeg:
        lat, lon = radians(lat), radians(lon)
    vec = np.array([
        cos(lat) * cos(lon),
        cos(lat) * sin(lon),
        (1 - e2) * sin(lat)
    ])
    norm = np.linalg.norm(vec)
    return vec / norm

target = (32.815130, -117.151695)
candidates = [
    (32.604187,  -117.005745),
    (37.920948,  -108.005043),
    (39.70122,   -104.876976),
    (38.844032,  -104.718307)
]

max(candidates, key=lambda x: np.dot(cartesianUnitVector(*x), cartesianUnitVector(*target)))

可以在Wikipedia找到大地测量到ECEF的公式。该示例显示了如何操作可迭代的lat-lon对。我不确定如何将其改编为熊猫,但你的问题是关于如何进行比较,我想我已经为此提供了答案。我相信一旦你定义了转换函数和使用它的比较键,你就可以毫不费力地将它应用到pandas了。