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

如何使用Pandas处理存在重叠的时间范围排序问题

解决方案:处理指令覆盖生成最终时间线快照

针对你描述的指令覆盖问题,我们可以通过时间区间分割+优先级筛选+区间合并的步骤,用Pandas实现最终的连续时间线快照。以下是具体实现步骤和代码:

核心思路

  1. 预处理数据:将时间字段转换为可比较的datetime类型,确保后续时间操作准确。
  2. 分割时间区间:提取所有指令的起始/结束时间,生成最小粒度的不重叠时间区间,确保每个区间只被单一优先级的指令覆盖。
  3. 筛选最高优先级指令:对每个最小区间,找到所有覆盖它的指令,保留编号(Number)最大的后续指令,确定该区间的层级。
  4. 合并相邻同层级区间:将连续的相同层级区间合并,得到简洁的最终时间线。

代码实现

1. 导入依赖并构造示例数据

import pandas as pd

# 构造你描述的示例输入数据
data = [
    {"Number": 9166, "timeFrom": "11:55", "timeTo": "11:59", "levelFrom": 0, "levelTo": 18},
    {"Number": 9166, "timeFrom": "11:59", "timeTo": "12:24", "levelFrom": 18, "levelTo": 18},
    {"Number": 9166, "timeFrom": "12:24", "timeTo": "12:27", "levelFrom": 18, "levelTo": 0},
    {"Number": 9167, "timeFrom": "11:59", "timeTo": "12:52", "levelFrom": 18, "levelTo": 18}
]
df = pd.DataFrame(data)

# 将时间字符串转换为datetime类型(假设为同一天,添加日期保证时间可比较)
df["timeFrom"] = pd.to_datetime("2024-01-01 " + df["timeFrom"])
df["timeTo"] = pd.to_datetime("2024-01-01 " + df["timeTo"])

2. 生成最小粒度时间区间

# 收集所有指令的时间点并排序
all_time_points = pd.concat([df["timeFrom"], df["timeTo"]]).unique()
all_time_points.sort()

# 生成所有不重叠的最小时间区间
time_intervals = []
for i in range(len(all_time_points) - 1):
    time_intervals.append({
        "start_time": all_time_points[i],
        "end_time": all_time_points[i+1]
    })
interval_df = pd.DataFrame(time_intervals)

3. 为每个区间匹配最高优先级的层级

def get_final_level(row):
    # 筛选出覆盖当前区间的所有指令:指令起始时间≤区间起始,指令结束时间≥区间结束
    mask = (df["timeFrom"] <= row["start_time"]) & (df["timeTo"] >= row["end_time"])
    matching_commands = df[mask]
    
    if matching_commands.empty:
        return None  # 无覆盖的区间可根据需求处理,这里直接丢弃
    
    # 取编号最大的后续指令的目标层级
    highest_priority_cmd = matching_commands.sort_values("Number", ascending=False).iloc[0]
    return highest_priority_cmd["levelTo"]

# 为每个区间分配最终层级
interval_df["level"] = interval_df.apply(get_final_level, axis=1)
# 过滤无覆盖的区间
interval_df = interval_df.dropna(subset=["level"])

4. 合并相邻同层级区间

# 合并连续的相同层级区间
merged_intervals = []
current_interval = interval_df.iloc[0].to_dict()

for idx in range(1, len(interval_df)):
    next_interval = interval_df.iloc[idx].to_dict()
    # 如果相邻且层级相同,合并结束时间
    if next_interval["level"] == current_interval["level"] and next_interval["start_time"] == current_interval["end_time"]:
        current_interval["end_time"] = next_interval["end_time"]
    else:
        merged_intervals.append(current_interval)
        current_interval = next_interval
merged_intervals.append(current_interval)

# 生成最终结果DataFrame
final_df = pd.DataFrame(merged_intervals)[["start_time", "end_time", "level"]]
# 转换回时间字符串格式(可选)
final_df["start_time"] = final_df["start_time"].dt.strftime("%H:%M")
final_df["end_time"] = final_df["end_time"].dt.strftime("%H:%M")

print(final_df)

输出结果

运行代码后,得到的最终时间线如下:

start_time end_time  level
0      11:55    11:59     18
1      11:59    12:52     18

完全符合你描述的需求:指令9167覆盖了9166中12:24返回0的部分,最终11:59到12:52保持18层级。

扩展说明

  • 优先级逻辑:这里默认Number越大的指令越晚到达,优先级越高。如果你的优先级规则不同,只需修改排序逻辑即可。
  • 初始状态处理:如果需要处理时间线起始前的初始层级,可以在最开始添加一个覆盖起始前区间的默认指令。
  • 跨天时间:如果涉及跨天时间,只需确保datetime字段包含完整的日期信息即可,代码无需修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 14:22:22