【问题标题】:How to calculate the closest latitude longitude for an entire column?如何计算整列的最近纬度经度?
【发布时间】:2019-06-05 15:51:13
【问题描述】:

我有一个地点事故的纬度列表,想看看离这些事故最近的警察局是什么。目前,事故的经纬度列表使用 pandas 在两个单独的列中(对不起,我对 python 很陌生,所以我可能会错误地使用单词)。派出所的经纬度目前在一个单独的 json 文件中。我目前的目标是创建一个新列(或文件),其中出现最近警察局的 latlongs。理想情况下,它应该是相应的名称,但那是我遇到它时会跨过的一座桥。

我查看了其他人是如何做到的,但除了询问位置,我只能询问一对 latlongs 的位置,而不是同时询问所有这些。

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 成为两列并将其放入新列。

我希望有一列显示最近警察局的经纬度。 有时我会遇到问题TypeError: string indices must be integers

【问题讨论】:

    标签: python json pandas dataframe latitude-longitude


    【解决方案1】:

    您可以在下面看到如何将索引列表转换为 numpy 数组,之后您可以对其进行操作,而无需遍历每个元素。

    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 访问例如每个警察局的名称或地址。

    希望对你有帮助。

    【讨论】:

    • 嗨!对不起,我可能对这个问题的表述有点困惑。 tempDataList 是警察局坐标的列表。我有一个单独的带有 pandas 的 df,其中包含两列“lat”和“lon”,我想将它们与 tempDataList 匹配。有没有办法将 df 的纬度与 tempDataList 中的纬度进行比较?不管怎样,非常感谢!
    • 在这种情况下,如果您保持其他所有内容相同,您只需将closest 中的axis=0 参数更改为axis=1。或者,通过警察局lat1lon1 和事故地点lat2lon2。无论哪种方式,您都可以通过确保警察局的数量与事故数量不同(出于测试目的)并确保closest 的输出长度等于事故数量来测试事物,而不是警察局
    猜你喜欢
    • 2015-10-19
    • 2017-04-05
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多