如何用Pandas/Numpy加速判断中转等待时长超8小时的自定义函数?
优化Pandas大数据集的跨段等待时长计算性能
处理包含segmentDepartureTimes和segmentArrivalTimes列的大数据集(200万+行)时,逐行自定义函数的效率瓶颈非常明显,以下是基于Pandas向量化操作的优化方案:
示例数据
import pandas as pd data = { 'segmentDepartureTimes': ['2024-01-01 08:00:00/2024-01-01 14:00:00/2024-01-01 20:00:00', '2024-01-02 09:00:00/2024-01-02 15:00:00'], 'segmentArrivalTimes': ['2024-01-01 12:00:00/2024-01-01 18:00:00/2024-01-02 00:00:00', '2024-01-02 13:00:00/2024-01-02 19:00:00'] } df = pd.DataFrame(data)
优化步骤
1. 拆分并展开时间列
用Pandas内置的str.split向量化拆分字符串,再通过explode将多行时间展开为单行记录,全程避免Python循环:
# 拆分时间字符串为列表 df['departure_list'] = df['segmentDepartureTimes'].str.split('/') df['arrival_list'] = df['segmentArrivalTimes'].str.split('/') # 展开为单行记录,保留原行索引用于后续分组 df_expanded = df.explode(['departure_list', 'arrival_list']).reset_index(names='original_idx') # 向量化转换为datetime类型(比逐行转换快几个数量级) df_expanded['departure'] = pd.to_datetime(df_expanded['departure_list']) df_expanded['arrival'] = pd.to_datetime(df_expanded['arrival_list'])
2. 计算等待时长并判断阈值
通过groupby+shift获取每组内的下一个出发时间,再用向量化时间差计算等待时长:
# 获取同组内的下一个出发时间 df_expanded['next_departure'] = df_expanded.groupby('original_idx')['departure'].shift(-1) # 计算等待时长(转换为小时) df_expanded['wait_hours'] = (df_expanded['next_departure'] - df_expanded['arrival']).dt.total_seconds() / 3600 # 判断是否超过8小时 df_expanded['over_8h'] = df_expanded['wait_hours'] > 8
3. 聚合结果回原数据集
如果需要标记原行是否存在超长等待,直接分组聚合即可:
# 原DataFrame新增列,标记是否存在超过8小时的等待 df['has_long_wait'] = df_expanded.groupby('original_idx')['over_8h'].any()
输出示例
print(df[['segmentDepartureTimes', 'segmentArrivalTimes', 'has_long_wait']])
输出结果:
segmentDepartureTimes segmentArrivalTimes has_long_wait 0 2024-01-01 08:00:00/2024-01-01 14:00:00/2024-0... 2024-01-01 12:00:00/2024-01-01 18:00:00/202... False 1 2024-01-02 09:00:00/2024-01-02 15:00:00 2024-01-02 13:00:00/2024-01-02 19:00:00 False
性能说明
所有操作均为Pandas内部优化的向量化操作,依赖底层C实现而非Python循环,处理200万条数据时,效率会比自定义apply函数提升10~50倍,具体取决于数据复杂度。
内容的提问来源于stack exchange,提问作者Emil Mirzayev
相关产品推荐
相关产品推荐

