
本文介绍如何利用 piso 库的区间分割与重叠检测能力,将原始巡检记录(含起止里程和时间)自动切分为互斥最小区间,并为每个区间提取最晚一次覆盖该区间的巡检时间。
本文介绍如何利用 piso 库的区间分割与重叠检测能力,将原始巡检记录(含起止里程和时间)自动切分为互斥最小区间,并为每个区间提取最晚一次覆盖该区间的巡检时间。
在基础设施资产管理(如道路、管道、电网线路)中,常需基于不规则、有重叠的巡检记录,推导出每一段连续区间的“最新被检查时间”。这类问题本质是区间覆盖+时间优先级聚合,而 piso(Pandas Interval Set Operations)专为此类操作设计,可避免手动循环或复杂合并逻辑。
以下是一个完整、可运行的解决方案:
import pandas as pd
import piso
# 原始巡检数据:[From_Mi, To_Mi, Date]
all_df = pd.DataFrame(
data=[
(0, 5, pd.Timestamp("2025-01-01")),
(2, 5, pd.Timestamp("2025-01-08")),
(0, 3, pd.Timestamp("2025-01-15")),
(0, 2, pd.Timestamp("2025-01-22")),
],
columns=["From_Mi", "To_Mi", "Date"]
)
# 步骤 1:按时间升序排序(确保后续 .iloc[-1] 取到最新日期)
all_df = all_df.sort_values("Date", ascending=True).reset_index(drop=True)
# 步骤 2:构建 IntervalArray(闭区间默认为左闭右开,但 piso 支持自定义)
arr = pd.arrays.IntervalArray.from_arrays(
all_df["From_Mi"], all_df["To_Mi"], closed="both"
)
# 步骤 3:获取所有端点(From_Mi 和 To_Mi 的并集),用于精确切分
breakpoints = sorted(set(arr.left).union(set(arr.right)))
# 步骤 4:用 piso.split() 将所有原始区间按端点切分为非重叠的最小原子区间
# 返回的是 IntervalArray,每个元素代表一个不可再分的连续子区间
unique_intervals = piso.split(arr, breakpoints).unique()
# 步骤 5:将原始记录转为以区间为索引的 Series,便于按区间快速查找重叠记录
interval_index = pd.IntervalIndex(arr, closed="both")
dates_series = all_df.set_index(interval_index)["Date"]
# 步骤 6:对每个唯一原子区间,找出所有与其重叠的原始巡检记录,并取最新日期
recent_records = []
for ui in unique_intervals:
# overlaps() 返回布尔索引;iloc[-1] 取排序后最后一个(即最新)
overlapping_dates = dates_series[dates_series.index.overlaps(ui)]
if len(overlapping_dates) > 0:
recent_records.append({
"From_Mi": ui.left,
"To_Mi": ui.right,
"Last_Date": overlapping_dates.iloc[-1]
})
# 构建最终结果 DataFrame
recent_df = pd.DataFrame(recent_records)
print(recent_df)
输出结果为:
From_Mi To_Mi Last_Date 0 0 2 2025-01-22 1 2 3 2025-01-15 2 3 5 2025-01-08
✅ 关键要点说明:
-
piso.split(arr, breakpoints)是核心——它将原始重叠区间集“栅格化”为一组互斥、端点对齐的原子区间; - 使用
closed="both"确保端点(如 mile 2)被正确归属(避免因开闭区间导致边界遗漏); - 排序必须在构建
IntervalIndex前完成,否则.iloc[-1]无法保证取到最新时间; - 若存在某原子区间未被任何巡检覆盖,
overlapping_dates为空,代码中已做安全判断(可依需改为pd.NaT或跳过)。
? 进阶提示: 对于超大规模数据(>10⁵ 条记录),建议改用 piso.coverage() + piso.union() 配合向量化时间聚合,或结合 numba 加速重叠判断;但对常规资产台账(数千条),本方案兼具清晰性与性能。










