Python处理Excel:Card Task数据分组与时间重叠统计问题
解决按Card Task分组统计时间重叠任务的问题
嘿,我看你现在卡在没法对同一Card Task内的行做配对比较的问题上了,咱们一步步来搞定它!核心问题是你还没把同一Card Task的行归拢到一起,所以没法在组内做相邻行的时间对比。下面是具体的解决思路和修改后的代码:
第一步:先把数据按Card Task分组
我们可以用一个字典来存储分组,键是Card Task的名称(比如"Card Task A"),值是该组对应的所有行数据。这样就能把同一任务的行都聚在一起,方便后续处理。
第二步:处理时间类型转换
要注意Excel里的时间可能是字符串或者datetime对象,直接比较字符串容易出错,所以最好把lastExecTime(N列)和M列的时间都转换成datetime类型再做比较。
第三步:组内相邻行对比统计
对每个分组里的行,按顺序遍历相邻的两行,比较前一行的N列时间和后一行的M列时间,如果后者更小,就计数加1,同时记录重叠的任务信息。
修改后的完整代码
from openpyxl import load_workbook from datetime import datetime # 加载Excel文件,data_only=True确保读取单元格的实际值而非公式 book = load_workbook('LearnerSummaryNoFormat.xlsx', data_only=True) sheet = book['Sheet1'] # 初始化分组字典:键是Card Task名称,值是对应的行列表 task_groups = {} current_task = None # 遍历所有行(跳过表头,假设第一行是表头,从第二行开始) for row in list(sheet.rows)[1:]: e_col_value = row[4].value # E列对应索引4(A列是索引0) if e_col_value and isinstance(e_col_value, str) and e_col_value.startswith('Card Task'): # 提取当前Card Task名称 current_task = e_col_value # 若该任务未在字典中,初始化空列表 if current_task not in task_groups: task_groups[current_task] = [] # 将当前行加入对应任务组 task_groups[current_task].append(row) elif current_task is not None: # 属于当前Card Task的后续行(E列无标识但归为当前组),直接加入 task_groups[current_task].append(row) else: # 不属于任何Card Task的行,打印提示 print(f"Is not a card task: {row[1].value}") # 准备统计结果 result_content = [] for task_name, rows in task_groups.items(): overlap_count = 0 overlapping_details = [] # 遍历组内相邻行(从第0行到倒数第二行) for i in range(len(rows) - 1): current_row = rows[i] next_row = rows[i+1] # 获取N列(lastExecTime)和M列的值,这里假设N是第13列、M是第12列,可根据实际调整 try: # 转换时间格式,需匹配Excel里的实际时间字符串格式 last_exec_time = current_row[13].value if isinstance(last_exec_time, str): last_exec_time = datetime.strptime(last_exec_time, "%Y-%m-%d %H:%M:%S") next_m_time = next_row[12].value if isinstance(next_m_time, str): next_m_time = datetime.strptime(next_m_time, "%Y-%m-%d %H:%M:%S") except ValueError as e: print(f"行{i+2}与{i+3}时间格式转换失败:{e}") continue # 判断时间重叠:下一行M列时间早于当前行N列时间 if next_m_time < last_exec_time: overlap_count += 1 overlapping_details.append(f"行{i+2} ↔ 行{i+3}:当前lastExecTime={last_exec_time}, 下一行M列时间={next_m_time}") # 整理当前任务的统计结果 result_content.append(f"=== {task_name} ===") result_content.append(f"重叠次数:{overlap_count}") if overlapping_details: result_content.append("重叠任务详情:") result_content.extend(overlapping_details) result_content.append("\n") # 生成统计结果文本文件 with open("task_overlap_report.txt", "w", encoding="utf-8") as f: f.write("\n".join(result_content)) print("统计完成,已生成task_overlap_report.txt")
关键说明
- 分组逻辑:当遇到E列是
Card Task开头的行时,切换当前任务组,后续的行(直到下一个Card Task出现)都自动归入这个组,完美解决了同一任务内数据的聚合问题。 - 时间处理:加入了时间类型转换,避免直接比较字符串导致的逻辑错误,你需要根据Excel里实际的时间格式调整
strptime的格式参数。 - 结果输出:最终生成的文本文件会清晰展示每个Card Task的重叠次数和具体的重叠行信息,方便查看。
内容的提问来源于stack exchange,提问作者A. Bhatnagar
相关产品推荐
相关产品推荐

