You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求Pandas DataFrame高效向量化方案:解决机场航班事件迭代问题

高效处理航班跑道重叠事件的向量化/Numba方案

我完全懂你在超大数据集下用嵌套逐行迭代Pandas DataFrame的崩溃感——这种方法不仅慢到离谱,还会吃掉大量内存。下面针对你提出的两个核心场景,我会给出基于向量化操作和Numba即时编译的高效解决方案,彻底摆脱迭代的性能瓶颈。


场景1:生成单跑道多航班重叠事件列表(不含子集事件)

核心思路

我们需要按跑道分组,对每个跑道的航班时间区间,找出所有最大连续重叠窗口:也就是每个窗口内的航班两两之间存在时间重叠(或衔接),且无法再加入其他航班的集合。这类窗口对应的航班集合自然不会是其他集合的子集,完全符合需求。

实现方案(Numba加速版)

Numba可以把Python循环编译成机器码,处理时间区间重叠的效率比纯Pandas向量化还要高,尤其适合超大数据集:

import numba
import pandas as pd
import numpy as np

@numba.jit(nopython=True)
def find_max_overlapping_groups(starts, ends, indices):
    # 先按开始时间排序,这是高效找重叠的基础
    sort_idx = np.argsort(starts)
    sorted_starts = starts[sort_idx]
    sorted_ends = ends[sort_idx]
    sorted_indices = indices[sort_idx]
    
    groups = []
    if len(sorted_starts) == 0:
        return groups
    
    # 初始化第一个重叠组
    current_end = sorted_ends[0]
    current_group = [sorted_indices[0]]
    
    for i in range(1, len(sorted_starts)):
        if sorted_starts[i] <= current_end:
            # 当前航班与组内航班重叠,加入组并更新组的最晚结束时间
            current_group.append(sorted_indices[i])
            if sorted_ends[i] > current_end:
                current_end = sorted_ends[i]
        else:
            # 重叠结束,保存当前组并初始化新组
            groups.append(current_group)
            current_end = sorted_ends[i]
            current_group = [sorted_indices[i]]
    # 保存最后一个组
    groups.append(current_group)
    
    # 过滤掉只有单个航班的无效组
    return [g for g in groups if len(g) > 1]

# 假设你的DataFrame结构为:df = pd.DataFrame({'runway': ['RWY1', 'RWY1', 'RWY2'], 'start': [1,3,2], 'end': [5,7,6], ...})
def generate_single_runway_events(df):
    events = []
    # 按跑道分组处理每个跑道的航班
    for runway, group_df in df.groupby('runway'):
        starts = group_df['start'].values
        ends = group_df['end'].values
        indices = group_df.index.values
        # 调用Numba函数获取当前跑道的所有有效重叠组
        runway_groups = find_max_overlapping_groups(starts, ends, indices)
        events.extend(runway_groups)
    return events

关键说明

  • 时间复杂度为O(n log n)(主要来自排序),比嵌套迭代的O(n²)快几个数量级。
  • 自动过滤单航班组,且每个返回的组都是该跑道上的最大重叠集合,不存在子集事件。

场景2:生成多跑道同时有航班的最大规模事件列表

核心思路

要找出至少两条跑道同时有航班运行的最大时间窗口,并记录窗口内的所有航班索引,核心步骤是:

  1. 收集所有航班的时间端点(开始/结束),作为时间分割点。
  2. 对每个时间区间,统计有航班运行的跑道数量,筛选出跑道数≥2的区间。
  3. 合并相邻的符合条件的区间,得到最大的连续窗口。
  4. 找出每个窗口内的所有航班,收集它们的索引。

实现方案(向量化+Numba结合)

@numba.jit(nopython=True)
def get_flights_in_window(starts, ends, window_start, window_end):
    # 快速筛选出窗口内的航班:航班开始时间≤窗口结束,且航班结束时间≥窗口开始
    mask = (starts <= window_end) & (ends >= window_start)
    return np.where(mask)[0]

def generate_multi_runway_max_events(df):
    # 收集所有时间端点并去重排序,生成所有可能的时间分割点
    all_times = np.concatenate([df['start'].values, df['end'].values])
    all_times = np.unique(np.sort(all_times))
    
    # 生成所有相邻时间点组成的区间
    intervals = np.array([(all_times[i], all_times[i+1]) for i in range(len(all_times)-1)])
    
    # 预处理数组,避免重复索引
    starts = df['start'].values
    ends = df['end'].values
    runways = df['runway'].values
    
    # 统计每个区间内有航班运行的跑道数量
    runway_count = []
    for start, end in intervals:
        mask = (starts <= end) & (ends >= start)
        active_runways = np.unique(runways[mask])
        runway_count.append(len(active_runways))
    
    runway_count = np.array(runway_count)
    # 筛选出至少两条跑道有航班的区间
    valid_intervals = intervals[runway_count >= 2]
    
    if len(valid_intervals) == 0:
        return []
    
    # 合并相邻的有效区间,得到最大连续窗口
    merged_windows = []
    current_start, current_end = valid_intervals[0]
    for s, e in valid_intervals[1:]:
        if s <= current_end:
            # 相邻区间合并,扩展窗口结束时间
            current_end = max(current_end, e)
        else:
            merged_windows.append((current_start, current_end))
            current_start, current_end = s, e
    merged_windows.append((current_start, current_end))
    
    # 找出每个最大窗口内的所有航班索引
    events = []
    for win_start, win_end in merged_windows:
        flight_positions = get_flights_in_window(starts, ends, win_start, win_end)
        flight_indices = df.index[flight_positions].tolist()
        events.append(flight_indices)
    
    return events

关键说明

  • 用向量化方法生成时间分割点,避免逐行遍历的低效操作。
  • Numba加速的get_flights_in_window函数比Pandas布尔索引更快,尤其适合超大数据集。
  • 合并相邻有效区间确保返回的是最大规模的事件,自动排除了被包含的子窗口和单跑道事件。

额外性能优化建议

  • 如果数据集达到千万级以上,可以结合Dask DataFrame做分块并行处理,进一步提升效率。
  • 建议将时间字段转换为整数类型(比如Unix时间戳),Numba处理整数的速度远快于datetime类型。

内容的提问来源于stack exchange,提问作者marillion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:25:27