
本文介绍一种基于断点提取与区间重组的方法,将两个含不规则区间(from-to)的数据框合并为统一细粒度区间,并按实际覆盖关系分配数值(如int),适用于地理范围、时间窗口或资源分配等场景。
本文介绍一种基于断点提取与区间重组的方法,将两个含不规则区间(from-to)的数据框合并为统一细粒度区间,并按实际覆盖关系分配数值(如int),适用于地理范围、时间窗口或资源分配等场景。
在处理区间型数据(如路段、时间段、IP段)时,常需将多个来源的不连续、有重叠或嵌套的区间合并为一套无重叠、全覆盖的最小单元区间,并为每个单元赋予合理的聚合值(如长度、权重或叠加计数)。本例中,df1 和 df2 分别代表两组区间及其属性 int,目标不是简单外连接,而是识别所有自然分割点(breakpoints)→ 构建原子区间 → 为每个原子区间计算其在原始数据中的有效贡献。
核心思路是:所有区间的端点(from 和 to)共同定义了最细粒度的划分边界。我们将这些端点去重、排序后,两两配对生成互斥的原子区间 [breakpoints[i], breakpoints[i+1]),再根据每个原子区间是否被原始区间完全覆盖,决定其 int 值的来源或计算逻辑。
以下为完整实现步骤:
步骤 1:提取并合并所有断点
import pandas as pd
df1 = pd.DataFrame({
'from': [0, 2, 8, 26, 35, 46],
'to': [2, 8, 26, 35, 46, 48],
'int': [2, 6, 18, 9, 11, 2]
})
df2 = pd.DataFrame({
'from': [0, 2, 8, 17, 34],
'to': [2, 8, 17, 34, 49],
'int': [2, 6, 9, 17, 15]
})
# 合并所有端点并去重排序
breakpoints = sorted(set(df1['from']) | set(df1['to']) | set(df2['from']) | set(df2['to'])得到 breakpoints = [0, 2, 8, 17, 26, 34, 35, 46, 48, 49]
步骤 2:构建原子区间框架
# 由断点生成相邻区间
new_df = pd.DataFrame({
'from': breakpoints[:-1],
'to': breakpoints[1:]
})此时 new_df 包含 9 行原子区间,但 int 列尚未赋值。
步骤 3:为每个原子区间分配 int 值(关键逻辑)
⚠️ 注意:原答案中直接设 int = to - from 是特例假设(即按长度赋值),但题干目标输出的 int 并非全为长度(例如 from=17, to=26 → int=9 符合长度,但 from=34, to=35 → int=1 也符合;而 from=26, to=34 → int=8 同样是长度)。观察目标 df 的 int 列:
-
[2,6,9,9,8,1,11,2,1] - 对应长度:
[2,6,9,9,8,1,11,2,1]—— 完全一致。
因此,本例中 int 的语义即为区间长度(to - from)。若业务中 int 表示其他含义(如覆盖次数、加权均值),则需改用区间覆盖判断逻辑,例如:
# 【进阶】若 int 表示「被至少一个原始区间覆盖的次数」
def count_coverage(row, dfs):
cnt = 0
for df in dfs:
# 检查当前原子区间 [row['from'], row['to']] 是否被 df 中任一区间包含(注意:此处为闭区间覆盖判定)
mask = (df['from'] <= row['from']) & (df['to'] >= row['to'])
if mask.any():
cnt += 1
return cnt
new_df['int'] = new_df.apply(lambda r: count_coverage(r, [df1, df2]), axis=1)但根据题干目标输出与示例数据严格匹配 int == to - from,我们采用简洁方式:
new_df['int'] = new_df['to'] - new_df['from']
最终结果:
from to int 0 0 2 2 1 2 8 6 2 8 17 9 3 17 26 9 4 26 34 8 5 34 35 1 6 35 46 11 7 46 48 2 8 48 49 1
✅ 完全匹配预期 df。
注意事项
- 该方法假设所有区间为左闭右闭(或左闭右开)且端点为整数;若为浮点或时间戳,需确保精度一致,必要时使用
np.round或pd.IntervalIndex。 - 若
int需表示加权叠加(如取最大值、平均值),应在步骤 3 中对每个原子区间查询所有覆盖它的原始区间,再聚合其int值。 - 性能提示:当断点数量极大(如百万级)时,
apply可能较慢,建议改用向量化区间合并库(如portion或piso)或基于merge_asof的优化策略。
此方案以“断点驱动”为核心,兼顾可读性与扩展性,是处理多源区间数据融合的通用范式。

















