如何最优合并含重叠范围标签的两个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
相关产品推荐
相关产品推荐

