使用Python基于CSV公交数据计算站点间路段时间间隔
处理公交CSV数据生成路段信息并计算耗时
步骤说明与代码实现
1. 导入依赖库
import pandas as pd from datetime import timedelta
2. 读取并预处理数据
先读取CSV文件,再处理公交数据中常见的跨天时间格式(如25:00:00),将时间转换为可计算的timedelta类型:
# 读取目标CSV文件 df = pd.read_csv('your_bus_data.csv') # 解析时间字符串为timedelta,兼容跨天时间 def parse_bus_time(time_str): h, m, s = map(int, time_str.split(':')) return timedelta(hours=h, minutes=m, seconds=s) df['arrival_delta'] = df['arrival_time'].apply(parse_bus_time)
3. 按行程分组计算路段信息
按trip_id分组后,每组内按stop_sequence排序,接着提取下一站的信息并计算路段耗时:
# 按行程ID分组,组内按站点顺序排序 df_sorted = df.sort_values(['trip_id', 'stop_sequence']).reset_index(drop=True) # 同行程内,获取下一站的站点ID和到达时间 df_sorted['next_stop_id'] = df_sorted.groupby('trip_id')['stop_id'].shift(-1) df_sorted['next_arrival_delta'] = df_sorted.groupby('trip_id')['arrival_delta'].shift(-1) # 计算路段耗时(转换为秒) df_sorted['segment_duration_sec'] = (df_sorted['next_arrival_delta'] - df_sorted['arrival_delta']).dt.total_seconds() # 过滤无下一站的行(每个行程的最后一个站点) segment_df = df_sorted.dropna(subset=['next_stop_id', 'segment_duration_sec']).copy() # 生成路段唯一标识(起点站点ID-终点站点ID) segment_df['segment_id'] = segment_df.apply(lambda row: f"{row['stop_id']}-{row['next_stop_id']}", axis=1)
4. 整理最终路段数据
保留核心字段,按需转换时间格式:
final_segment_df = segment_df[[ 'trip_id', 'segment_id', 'stop_id', 'next_stop_id', 'arrival_time', 'segment_duration_sec', 'stop_headsign' ]] # 可选:将下一站到达时间转换回字符串格式 final_segment_df['next_arrival_time'] = df_sorted['next_arrival_delta'].apply(lambda x: str(x))
5. 共享路段分析
若需统计同一路段在不同行程中的耗时情况,可按segment_id分组聚合:
segment_stats = final_segment_df.groupby('segment_id').agg( avg_duration_sec=('segment_duration_sec', 'mean'), min_duration_sec=('segment_duration_sec', 'min'), max_duration_sec=('segment_duration_sec', 'max'), related_trips=('trip_id', 'nunique') ).reset_index()
关键注意事项
- 排序优先级:必须确保每个
trip_id下的站点按stop_sequence升序排列,否则时间差计算会完全错误。 - 跨天时间兼容:使用
timedelta类型处理时间,可自动解决25:00:00这类跨天时间的差值计算问题。 - 无效数据过滤:每个行程的最后一个站点没有后续站点,必须过滤掉这类行以避免无效计算结果。
内容的提问来源于stack exchange,提问作者peetman
相关产品推荐
相关产品推荐

