Как рассчитать ближайшую широту долготы для всего столбца? - PullRequest
1 голос
/ 05 июня 2019

У меня есть список самых разных мест происшествий, и я хочу узнать, какой полицейский участок был ближе всего к каждому из этих происшествий.В настоящее время список лонглонгов о происшествиях находится в двух отдельных столбцах с использованием панд (извините, я очень плохо знаком с python, поэтому могу неправильно использовать слова).Latlongs полицейского участка в настоящее время находятся в отдельном файле JSON.Моя текущая цель - создать новый столбец (или файл), в котором появляются латлонги ближайшего полицейского участка.В идеале это было бы соответствующее имя, но это мост, который я перейду, когда подойду к нему.

Я смотрел, как это делали другие люди, но не мог идти дальше, чем спрашивать местоположениетолько одна пара латлонгов и не все одновременно.

from math import cos, asin, sqrt

def distance (lat1, lon1, lat2, lon2):
    p = 0.017453292519943295
    a = 0.5 - cos((lat2-lat1)*p)/2 + cos(lat1*p)*cos(lat2*p) * (1-cos((lon2-lon1)*p)) / 2
    return 12742 * asin(sqrt(a))

def closest(data, v):
    return min(data, key=lambda p: distance(v['lat'],v['lon'],p['lat'],p['lon']))

#these are the latlons of the police stations
tempDataList = [{"lat": 52.003181, "lon": 4.353068}, 
    {"lat": 52.089416, "lon": 4.377340},
    {"lat": 52.019911, "lon": 4.426602},
    {"lat": 52.054457, "lon": 4.388764},
    {"lat": 52.044536, "lon": 4.332631},
    {"lat": 52.072910, "lon": 4.274784},
    {"lat": 52.066099, "lon": 4.298664},
    {"lat": 52.070030, "lon": 4.317355},
    {"lat": 52.052636, "lon": 4.289576},
    {"lat": 52.060829, "lon": 4.318683},
    {"lat": 52.075680, "lon": 4.306810},
    {"lat": 52.040353, "lon": 4.256946},
    {"lat": 52.089381, "lon": 4.345599},
    {"lat": 52.111719, "lon": 4.283909},
    {"lat": 52.055222, "lon": 4.233827},
    {"lat": 52.046393, "lon": 4.253105},
    {"lat": 52.144177, "lon": 4.405549},
    {"lat": 51.987035, "lon": 4.199314},
    {"lat": 52.061650, "lon": 4.486572}]

v = {'lat': 52.103167, 'lon': 4.317532}
print(closest(tempDataList, v))

Здесь я терплю неудачу, потому что я просто не знаю, как получить v в виде двух столбцов и поместить его вновый столбец.

Я надеюсь, что столбец, в котором показаны latlong ближайшего полицейского участка.Иногда я сталкиваюсь с проблемой TypeError: string indices must be integers.

1 Ответ

0 голосов
/ 05 июня 2019

Ниже вы можете увидеть, как преобразовать ваш список индексов в массивы, с которыми вы можете впоследствии работать, не просматривая каждый элемент.

import numpy as np
# numpy allows you to work with arrays; math only works with scalars
from numpy import cos, arcsin as asin, sqrt

def distance (lat1, lon1, lat2, lon2):
    """Return the distances between all accidents (lat1,lon1)
    and all police stations (lat2,lon2) as a 2-dimensional array
    """
    # add dummy dimension to p
    lat2 = lat2[:,None]
    lon2 = lon2[:,None]
    p = 0.017453292519943295
    a = 0.5 - cos((lat2-lat1)*p)/2 + cos(lat1*p)*cos(lat2*p) * (1-cos((lon2-lon1)*p)) / 2
    return 12742 * asin(sqrt(a))

def closest(*args):
    """Returns the index (counting from zero) of the closest
    police station for every accident.
    """
    return np.argmin(distance(*args), axis=0)


tempDataList = [{"lat": 52.003181, "lon": 4.353068},
    {"lat": 52.089416, "lon": 4.377340},
    {"lat": 52.019911, "lon": 4.426602},
    {"lat": 52.054457, "lon": 4.388764},
    {"lat": 52.044536, "lon": 4.332631},
    {"lat": 52.072910, "lon": 4.274784},
    {"lat": 52.066099, "lon": 4.298664},
    {"lat": 52.070030, "lon": 4.317355},
    {"lat": 52.052636, "lon": 4.289576},
    {"lat": 52.060829, "lon": 4.318683},
    {"lat": 52.075680, "lon": 4.306810},
    {"lat": 52.040353, "lon": 4.256946},
    {"lat": 52.089381, "lon": 4.345599},
    {"lat": 52.111719, "lon": 4.283909},
    {"lat": 52.055222, "lon": 4.233827},
    {"lat": 52.046393, "lon": 4.253105},
    {"lat": 52.144177, "lon": 4.405549},
    {"lat": 51.987035, "lon": 4.199314},
    {"lat": 52.061650, "lon": 4.486572}]

# first get lat and lon into arrays
lat, lon = np.transpose([[i['lat'],i['lon']] for i in tempDataList])

# I'm making up the police stations here. Say 5 police stations.
# you should load the actual data in your problem. My station locations
# are randomly located near the first 5 accidents
npolice = 5
# for reproducibility
np.random.seed(3)
plat = lat[:npolice] + np.random.normal(0, 0.02, npolice)
plon = lon[:npolice] + np.random.normal(0, 0.02, npolice)

index = closest(lat, lon, plat, plon)
# index = array([3, 1, 2, 0, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 1, 4, 2])

Так что ближайшие пункты полицейского участка будут

nearest = {'lat': plat[index], 'lon': plon[index]}

и вы можете использовать index для доступа, скажем, к названию или адресу каждого полицейского участка, если вы также сохранили их.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...