Pandas基于时间条件合并更新区域车辆供给数据的实现方案咨询
车辆调度动态供给匹配实现方案
核心思路
该需求属于时序驱动的状态更新场景,不能用常规静态表join实现,需要按调度发生顺序逐行处理,结合优先队列(最小堆)维护未完成的调度记录,高效触发供给数更新。
实现步骤
- 预处理数据:
- 将df2的
start_dt、end_dt统一转换为可比较的datetime类型/时间戳整数,避免时间比较错误 - 把df1转换为以区域ID为key的字典存储初始供给,方便后续快速读写
- 对df2按
start_dt升序排序,保证处理顺序和调度实际发生顺序一致
- 将df2的
- 初始化变量:
- 维护全局当前供给字典
current_supply,初始值复制df1的初始供给数据 - 维护最小堆
pending_trips,存储格式为(到达时间end_dt, 出发区域, 到达区域),堆顶永远是最早完成的调度 - 为df2新增
matched_supply列,用来存储匹配到的出发区域实时供给数
- 维护全局当前供给字典
- 逐行处理调度记录:
- 先处理所有已完成的历史调度:循环判断堆顶调度的到达时间 <= 当前调度的出发时间,若满足则弹出该调度,更新对应区域的供给数(出发区域-1,到达区域+1),直到堆为空或堆顶调度未完成
- 匹配当前调度的供给:取
current_supply中对应出发区域的数值,写入当前行的matched_supply字段 - 将当前调度加入最小堆,等待后续到达后触发供给更新
代码示例
import pandas as pd import heapq # 数据预处理 df2['start_dt'] = pd.to_datetime(df2['start_dt']) df2['end_dt'] = pd.to_datetime(df2['end_dt']) # 按出发时间升序排列调度记录 df2 = df2.sort_values(by='start_dt', ignore_index=True) # 初始供给转字典 current_supply = df1.set_index('start')['supply_cnt'].to_dict() # 初始化待完成调度堆与结果列 pending_trips = [] df2['matched_supply'] = 0 # 遍历处理所有调度 for idx, row in df2.iterrows(): # 先更新所有已完成调度对应的供给 while pending_trips and pending_trips[0][0] <= row['start_dt']: finished_end_dt, s_area, e_area = heapq.heappop(pending_trips) current_supply[s_area] -= 1 current_supply[e_area] += 1 # 匹配当前调度出发区域的实时供给 df2.at[idx, 'matched_supply'] = current_supply[row['start']] # 当前调度加入待完成堆 heapq.heappush(pending_trips, (row['end_dt'], row['start'], row['end']))
方案优势
- 时间效率高:排序复杂度为O(n log n),每个调度进出堆各一次复杂度为O(n log k),k为同时进行的最大调度数,远优于逐行遍历所有历史调度的O(n²)方案
- 逻辑准确:严格按照调度完成时间触发供给更新,未完成的调度不会影响当前供给计算,完全符合需求规则
- 扩展性强:若需要额外处理调度取消等异常状态,只需要在堆中增加调度状态标识即可快速适配
内容的提问来源于stack exchange,提问作者Yun Hyunsoo
相关产品推荐
相关产品推荐

