如何过滤巴黎-里昂铁轨沿线两站之间的GPS经纬度数据
解决方案
问题根因
pandas.Series.between()要求输入的左边界小于右边界,你代码中纬度区间写反了:巴黎纬度48.844601高于里昂纬度45.760573,参数填反会直接导致纬度筛选条件全部失效。- 经纬度矩形框筛选逻辑本身有缺陷,里昂向南往马赛、图卢兹方向的部分区域也可能落在你设定的经纬度区间内,自然过滤不掉延伸行程的多余数据。
可行实现方案
步骤1:用距离计算替代矩形筛选
用半正矢(Haversine)公式计算GPS点到两个车站的球面距离,设置合理的进站阈值(例如500米,可根据实际数据调整),判断列车是否到达/离开站点。
步骤2:按行程截断数据
以train_id为单位分组,仅保留单趟行程中首次离开巴黎站阈值范围 到 首次进入里昂站阈值范围之间的数据(反向行程同理调整),彻底过滤掉里昂站之后的延伸段数据。
完整代码示例
import pandas as pd import numpy as np # 半正矢公式,计算两点间距离(单位:米) def haversine(lat1, lon1, lat2, lon2): R = 6371000 # 地球半径,单位米 phi1 = np.radians(lat1) phi2 = np.radians(lat2) delta_phi = np.radians(lat2 - lat1) delta_lambda = np.radians(lon2 - lon1) a = np.sin(delta_phi/2)**2 + np.cos(phi1)*np.cos(phi2)*np.sin(delta_lambda/2)**2 c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1-a)) return R * c # 车站坐标 paris_lat, paris_lon = 48.844601, 2.373777 lyon_lat, lyon_lon = 45.760573, 4.860163 # 进站阈值,可根据实际情况调整 threshold = 500 # 单位:米 # 计算每个点到两个车站的距离 gps_data['dist_to_paris'] = haversine(gps_data['latitude'], gps_data['longitude'], paris_lat, paris_lon) gps_data['dist_to_lyon'] = haversine(gps_data['latitude'], gps_data['longitude'], lyon_lat, lyon_lon) # 按列车分组处理每趟行程 filtered_dfs = [] for train_id, group in gps_data.groupby('train_id'): group = group.sort_values('timestamp').reset_index(drop=True) # 找离开巴黎站的最早时间点(距离大于阈值的第一个点) leave_paris_idx = group[group['dist_to_paris'] > threshold].index.min() # 找到达里昂站的最早时间点(距离小于阈值的第一个点) arrive_lyon_idx = group[group['dist_to_lyon'] < threshold].index.min() # 仅保留两个点之间的有效数据 if pd.notna(leave_paris_idx) and pd.notna(arrive_lyon_idx) and leave_paris_idx < arrive_lyon_idx: valid_group = group.loc[leave_paris_idx:arrive_lyon_idx].copy() filtered_dfs.append(valid_group) # 合并结果 df = pd.concat(filtered_dfs, ignore_index=True) # 可选:删除辅助计算列 df = df.drop(columns=['dist_to_paris', 'dist_to_lyon'])
优化说明
- 如果列车包含双向行程(里昂往巴黎),可以增加方向判断逻辑:先判断行程是从巴黎出发还是里昂出发,再对应调整起止索引的筛选规则。
- 阈值可以根据车站实际范围调整,如果数据存在GPS漂移可以适当调大到800~1000米。
内容的提问来源于stack exchange,提问作者MALAM
相关产品推荐
相关产品推荐

