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

如何最优合并含重叠范围标签的两个Pandas DataFrame?

Pandas实现重叠区间的多标签匹配最优方案

原始数据

import pandas as pd

df_1 = pd.DataFrame(
    {
        'a': [10, 12, 14, 20, 25, 30, 42, 50, 80]
    }
)

df_2 = pd.DataFrame(
    {
        'start': [9, 19],
        'end': [26, 50],
        'label': ['a', 'b']
    }
)

需求说明

给df_1添加label列,匹配规则:

  • df_2定义label对应数值范围:左开区间(start < x)、右闭区间(x ≤ end)
  • 区间存在重叠,符合多个区间的行需生成对应多label的行
  • 预期输出:
a    label
10    a
12    a
14    a
20    a
25    a
20    b
25    b
30    b
42    b
50    b

我的两种尝试

尝试1(可运行,但不确定是否最优)

# attempt_1
dfc = pd.DataFrame([])
for idx, row in df_2.iterrows():
    start = row['start']
    end = row['end']
    label = row['label']
    df_slice = df_1.loc[df_1.a.between(start, end, inclusive='right')]
    df_slice['label'] = label
    dfc = pd.concat([df_slice, dfc], ignore_index=True)

尝试2(无法满足需求)

## attempt 2
idx = pd.IntervalIndex.from_arrays(df_2['start'], df_2['end'], closed='both')
label = df_2.iloc[idx.get_indexer(df_1.a), 'label']
df_1['label'] = label.to_numpy()

注:该方法的问题在于get_indexer仅返回每个值匹配到的第一个区间索引,无法处理重叠区间的多标签输出,不符合需求。

最优实现方案

推荐使用交叉合并+条件过滤的向量化方案,比循环迭代效率更高,逻辑更清晰:

# 交叉合并两个DataFrame的所有行
merged = df_1.merge(df_2, how='cross')
# 过滤符合左开右闭区间的行
result = merged[(merged['a'] > merged['start']) & (merged['a'] <= merged['end'])]
# 调整列顺序并重置索引
result = result[['a', 'label']].reset_index(drop=True)

方案优势

  • 效率更高:Pandas向量化操作远快于iterrows循环,数据量越大优势越明显
  • 代码简洁:无需手动拼接DataFrame,逻辑直观易维护
  • 扩展性强:支持任意数量的重叠区间,无需修改核心逻辑

如果想进一步简化代码,可结合query方法:

result = df_1.merge(df_2, how='cross').query('a > start and a <= end')[['a', 'label']].reset_index(drop=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:01:06