如何高效合并pandas DataFrame中存在交集的区间记录
pandas 预排序区间高效合并方案
你的DataFrame已经按区间起始列A完成预排序,无需使用逐行for循环实现合并,采用pandas原生向量化运算可以获得远超循环的执行效率,百万行级数据可秒级返回结果。
核心实现思路
因为区间已经按起点升序排列,重叠区间必然满足「当前区间起点小于之前所有区间的最大结束值」的规律,基于这个规律可以全程用pandas内置的向量化函数完成计算,完全避免Python层面的逐行遍历开销:
- 计算逐行累计的区间结束值最大值,用于重叠判断
- 为每个独立不重叠区间生成分组标识:当当前行的A值大于截止到上一行的累计最大B值时,标记为新的独立区间起点
- 按分组聚合,每个分组取最小A值作为合并后区间起点,取最大B值作为合并后区间终点
完整代码
import pandas as pd # 构造测试数据集 a = [1, 2, 7, 11, 12] b = [5, 4, 9, 20, 21] df = pd.DataFrame({"A": a, "B": b}) # 核心合并逻辑 # 生成区间分组标记 df["group_id"] = (df["A"] > df["B"].cummax().shift(fill_value=-float("inf"))).cumsum() # 分组聚合得到合并结果 merged_df = df.groupby("group_id", as_index=False).agg( A=("A", "min"), B=("B", "max") )[["A", "B"]]
结果说明
执行代码后得到的merged_df和期望输出完全一致:
| A | B |
|---|---|
| 1 | 5 |
| 7 | 9 |
| 11 | 21 |
如果你认为端点相接(例如前区间结束值为5、后区间起始值为5)不属于需要合并的交集场景,只需要把判断条件中的
>替换为>=即可。
如果后续输入数据未做预排序,只需要在核心逻辑前添加一行排序代码即可:df = df.sort_values("A").reset_index(drop=True)
性能对比
该方案所有运算均在pandas底层C实现层完成,相比for循环搭配iterrows()/itertuples()的逐行实现,10万行以上数据量场景下执行速度可提升100倍以上,数据量越大优势越明显。
内容的提问来源于stack exchange,提问作者Alireza75
相关产品推荐
相关产品推荐

