Сравните геохеши между двумя фреймами данных pandas

У меня есть 2 фрейма данных df1 и df2 с разными широтой и долготой вместе с соответствующими геохешами. Теперь для каждого геохеша в df1 я хочу найти ближайший геохеш в кадре данных df2. Я не уверен, есть ли способ сравнить геохеши. Например, для идентификатора 121 в df1 ближайшим геохешем в df2 будет 9muc3rr, а для идентификатора 122 в df2 ближайшим геохешем будет 9wv97m1.

Фрейм данных df1

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

Фрейм данных 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

person user3447653    schedule 18.08.2016    source источник
comment
Вы смотрели geopandas?   -  person Jon Clements♦    schedule 18.08.2016
comment
Насколько мне известно, я не вижу в геопандах никаких методов для сравнения геохешей.   -  person user3447653    schedule 18.08.2016
comment
Разве ближайший геохеш - это не пары широты и долготы с кратчайшим расстоянием?   -  person Jon Clements♦    schedule 18.08.2016
comment
Да, ближайший геохеш возвращается к ближайшим парам широта / долгота   -  person user3447653    schedule 18.08.2016
comment
Если два геохеша не имеют общего префикса, пропорциональна ли их близость близости числового значения первого символа?   -  person Mad Physicist    schedule 18.08.2016
comment
Я поддерживаю голосование, потому что это познакомило меня с геохешированием, что довольно круто (но я полностью игнорирую его в своем решении).   -  person Mad Physicist    schedule 18.08.2016


Ответы (1)


Если вы готовы немного изобретать колесо, вы можете преобразовать пары (lat, lon) в декартовы единичные векторы, а затем просто сравнить их, используя точечное произведение. Поскольку скалярное произведение в основном является мерой проекции одного вектора на другой, произведение, наиболее близкое к 1 (максимум), будет наилучшим совпадением между двумя векторами.

Приведенный ниже пример расчета основан на этом ответе. Я сделаю предположение, что вы указываете геодезические координаты на эллипсоиде 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)))

Формулу преобразования геодезических в ECEF можно найти в Википедии. В примере показано, как работать с итерацией пар латин-долгон. Я не совсем уверен, как адаптировать это к пандам, но ваш вопрос о том, как проводить сравнение, и я думаю, что дал на это ответ. Я уверен, что после того, как вы определили функцию преобразования и ключ сравнения, который ее использует, у вас не будет проблем с применением этого к пандам.

person Mad Physicist    schedule 18.08.2016