Python 计算连续GPS点之间的距离,并根据该距离减少GPS密度

Python 计算连续GPS点之间的距离,并根据该距离减少GPS密度,python,pandas,Python,Pandas,我有一个熊猫数据框,它代表车辆的GPS轨迹 d1 = {'id': [1, 2, 3, 4, 5, 6, 7, 8, 9], 'longitude': [4.929783, 4.932333, 4.933950, 4.933900, 4.928467, 4.924583, 4.922133, 4.921400, 4.920967], 'latitude': [52.372250, 52.370884, 52.371101, 52.372234, 52.375282, 52.375950, 52.

我有一个熊猫数据框,它代表车辆的GPS轨迹

d1 = {'id': [1, 2, 3, 4, 5, 6, 7, 8, 9], 'longitude': [4.929783, 4.932333, 4.933950, 4.933900, 4.928467, 4.924583, 4.922133, 4.921400, 4.920967], 'latitude': [52.372250, 52.370884, 52.371101, 52.372234, 52.375282, 52.375950, 52.376301, 52.376232, 52.374481]}
df1 = pd.DataFrame(data=d1)

id   longitude   latitude     
1    4.929783    52.372250    
2    4.932333    52.370884    
3    4.933950    52.371101    
4    4.933900    52.372234    
5    4.928467    52.375282    
6    4.924583    52.375950    
7    4.922133    52.376301    
8    4.921400    52.376232    
9    4.920967    52.374481    

我已经计算了连续GPS点之间的(哈弗森)距离,单位为米,如下所示:

import numpy as np
def haversine(lat1, lon1, lat2, lon2, earth_radius=6371):
    lat1, lon1, lat2, lon2 = np.radians([lat1, lon1, lat2, lon2])

    a = np.sin((lat2-lat1)/2.0)**2 + np.cos(lat1) * np.cos(lat2) * np.sin((lon2-lon1)/2.0)**2
    km = earth_radius * 2 * np.arcsin(np.sqrt(a))
    m = km * 1000
    return m

df1['distance'] = haversine(df1['latitude'], df1['longitude'],
                       df1['latitude'].shift(), df1['longitude'].shift())

id  longitude   latitude    distance
1   4.929783    52.372250   NaN
2   4.932333    52.370884   230.305288
3   4.933950    52.371101   112.398101
4   4.933900    52.372234   126.029572
5   4.928467    52.375282   500.896578
6   4.924583    52.375950   273.918990
7   4.922133    52.376301   170.828592
8   4.921400    52.376232   50.345227
9   4.920967    52.374481   196.908503
现在我想创建一个函数

  • 如果连续GPS点之间的距离小于150米,则删除第二个点,即以下点

  • 始终保留最后一个(和第一个)GPS点,而不考虑前一个保留特征之间的距离

  • 这意味着这应该是输出:

    id  longitude   latitude    distance
    1   4.929783    52.372250   NaN
    2   4.932333    52.370884   230.305288
    5   4.928467    52.375282   500.896578
    6   4.924583    52.375950   273.918990
    7   4.922133    52.376301   170.828592
    9   4.920967    52.374481   196.908503
    
    在python中实现这一点的最佳方法是什么?

    注意:这并没有考虑到最大距离。。。这需要一些前瞻性和优化


    我将迭代并传回您想要保留的行的索引值。在
    loc
    调用中使用这些索引值

    距离 使用你想要的任何指标。我用了OP的哈弗森距离

    def haversine(lat1, lon1, lat2, lon2, earth_radius=6371):
        lat1, lon1, lat2, lon2 = np.radians([lat1, lon1, lat2, lon2])
    
        a = np.sin((lat2-lat1)/2.0)**2 + np.cos(lat1) * np.cos(lat2) * np.sin((lon2-lon1)/2.0)**2
        km = earth_radius * 2 * np.arcsin(np.sqrt(a))
        m = km * 1000
        return m
    
    def dis(t0, t1):
        lat0 = t0.latitude
        lon0 = t0.longitude
        lat1 = t1.latitude
        lon1 = t1.longitude
        return haversine(lat0, lon0, lat1, lon1)
    
    环路 结果
    您想保持最大距离吗?i、 e.如果点A、B、C使A、B“靠得太近”,而A、C“相距太远”,会发生什么情况?在这种情况下,你想删除A并保留B吗?很好。我希望保持最大距离为最小距离的2倍(即在这种情况下为100米)。这意味着id为nr 7的点也应该是Kepthanks,感谢您的回复!输出距离实际上似乎与实际距离不匹配。我已经用正确计算的距离更新了我的帖子。我已经用你的haversine函数更新了我的帖子。谢谢。尽管如此,我仍然在结果表中看到一些意想不到的距离。例如,id为
    4
    的坐标对的距离为
    183.986479
    。但是,我在未处理的表中看不到这个距离。这同样适用于id为
    9
    的坐标对,其计算距离为
    217.302775
    ,但在未处理的表格中,距离为
    196.908503
    。知道问题出在哪里吗?
    def f(d, threshold=50):
        itups = d.itertuples()
        
        last = next(itups)
        
        indices = [last.Index]
        distances = [0]
    
        for tup in itups:
            distance = dis(tup, last)
            if distance > threshold:
                indices.append(tup.Index)
                distances.append(distance)
                last = tup
                
        return indices, distances
            
    
    idx, distances = f(df1, 150)
    df1.loc[idx].assign(distance=distances)
    
       id  longitude   latitude    distance
    0   1   4.929783  52.372250    0.000000
    1   2   4.932333  52.370884  230.305288
    3   4   4.933900  52.372234  183.986479
    4   5   4.928467  52.375282  500.896578
    5   6   4.924583  52.375950  273.918990
    6   7   4.922133  52.376301  170.828592
    8   9   4.920967  52.374481  217.302775