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

如何用Python合并CSV文件中的重叠时间区间?

合并CSV中的重叠时间区间

示例CSV数据

姓名开始时间结束时间
John12:0013:00
John12:1013:00
John12:2013:20
Tom12:0013:10
John13:5014:00
Jerry14:0014:30
Alice15:0016:00
Jerry11:0015:00

需求说明

需要按姓名分组,合并每组内的重叠或相邻时间区间:

合并前

  • John: [12:00,13:00],[12:10,13:00],[12:20,13:20],[13:50,14:00]
  • Jerry: [14:00,14:30],[11:00,15:00]
  • Tom: [12:00,13:10]
  • Alice: [15:00,16:00]

合并后

  • John: [12:00,13:20],[13:50,14:00]
  • Jerry: [11:00,15:00]
  • Alice: [15:00,16:00]
  • Tom: [12:00,13:10]

现有代码问题

你当前的代码只存储了每个姓名的最后一个时间区间,并没有收集所有区间,也没有处理合并逻辑。修正后的完整解决方案如下:

完整解决方案代码

import csv
from datetime import datetime

def time_to_minutes(time_str):
    # 将HH:MM格式的时间转换为当天的总分钟数,方便数值比较
    dt = datetime.strptime(time_str, "%H:%M")
    return dt.hour * 60 + dt.minute

def merge_intervals(intervals):
    # 转换时间格式并按开始时间排序
    converted = [(time_to_minutes(start), time_to_minutes(end)) for start, end in intervals]
    converted.sort(key=lambda x: x[0])
    
    merged = []
    for interval in converted:
        if not merged:
            merged.append(interval)
        else:
            last_start, last_end = merged[-1]
            curr_start, curr_end = interval
            # 若当前区间与上一个重叠或相邻,则合并
            if curr_start <= last_end:
                new_end = max(last_end, curr_end)
                merged[-1] = (last_start, new_end)
            else:
                merged.append(interval)
    
    # 将分钟数转回HH:MM格式
    return [(f"{start//60:02d}:{start%60:02d}", f"{end//60:02d}:{end%60:02d}") for start, end in merged]

# 读取CSV并收集每个用户的所有时间区间
user_intervals = {}
with open('log.csv', mode='r') as csv_file:
    csv_reader = csv.DictReader(csv_file)
    # 注意:若CSV列名是Name/Start/End,替换成对应的键
    for row in csv_reader:
        name = row["姓名"]
        start = row["开始时间"]
        end = row["结束时间"]
        if name not in user_intervals:
            user_intervals[name] = []
        user_intervals[name].append((start, end))

# 对每个用户的区间执行合并并输出
for name, intervals in user_intervals.items():
    merged = merge_intervals(intervals)
    interval_str = ",".join([f"[{s},{e}]" for s,e in merged])
    print(f"{name}: {interval_str}")

代码说明

  1. time_to_minutes函数:把时间字符串转成可比较的分钟数,避免字符串比较的误差
  2. merge_intervals函数:
    • 先将所有区间转换为分钟数并按开始时间排序
    • 遍历排序后的区间,判断是否与已合并的最后一个区间重叠/相邻,是则合并,否则新增
    • 最后将合并后的分钟数转回HH:MM格式
  3. 数据收集:修正原代码的逻辑,收集每个用户的所有时间区间,而非仅最后一个
  4. 结果输出:遍历每个用户,合并区间后格式化输出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:17:02