如何用Python合并CSV文件中的重叠时间区间?
合并CSV中的重叠时间区间
示例CSV数据
| 姓名 | 开始时间 | 结束时间 |
|---|---|---|
| John | 12:00 | 13:00 |
| John | 12:10 | 13:00 |
| John | 12:20 | 13:20 |
| Tom | 12:00 | 13:10 |
| John | 13:50 | 14:00 |
| Jerry | 14:00 | 14:30 |
| Alice | 15:00 | 16:00 |
| Jerry | 11:00 | 15: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}")
代码说明
time_to_minutes函数:把时间字符串转成可比较的分钟数,避免字符串比较的误差merge_intervals函数:- 先将所有区间转换为分钟数并按开始时间排序
- 遍历排序后的区间,判断是否与已合并的最后一个区间重叠/相邻,是则合并,否则新增
- 最后将合并后的分钟数转回
HH:MM格式
- 数据收集:修正原代码的逻辑,收集每个用户的所有时间区间,而非仅最后一个
- 结果输出:遍历每个用户,合并区间后格式化输出
内容的提问来源于stack exchange,提问作者Bk thomas
相关产品推荐
相关产品推荐

