Python项目:将CSV中DateTo列的NULL替换为当日日期
解决CSV中DateTo为'NULL'时替换为当日日期并计算共事最久员工的方案
针对你的需求,其实完全不需要修改原CSV文件——只读模式打开完全没问题,我们只需要在读取数据的环节对DateTo字段做内存中的替换即可,不用写回原文件。下面分别给出原生Python和Pandas的完整解决方案:
一、原生Python代码修改版
你的原有逻辑已经很清晰,只需要在读取每行数据时,添加对ToDate是否为'NULL'的判断,用当前日期替换即可。这里用datetime.today().strftime('%Y-%m-%d')来生成符合格式的当日日期字符串:
from collections import defaultdict from itertools import combinations from datetime import datetime import csv d = defaultdict(list) # 获取当日日期,格式化为CSV中的日期格式 today = datetime.today().strftime('%Y-%m-%d') with open("data.csv") as f: next(f) # 跳过表头 r = csv.reader(f) for EmpID, ProjectID, FromDate, ToDate in r: # 处理ToDate为NULL的情况,兼容大小写和前后空格 if ToDate.strip().upper() == 'NULL': ToDate = today d[int(ProjectID)].append((EmpID, FromDate, ToDate)) # 统计共事时长并存储所有有效组合 collaboration_days = [] for job, aref in d.items(): if len(aref) >= 2: for ref in combinations(aref, 2): begin = max(map(lambda x: x[1], ref)) end = min(map(lambda x: x[2], ref)) # 捕获日期格式异常,避免程序崩溃 try: delta = datetime.strptime(end, '%Y-%m-%d') - datetime.strptime(begin, '%Y-%m-%d') dd = delta.days if dd > 0: collaboration_days.append( (ref[0][0], ref[1][0], job, dd) ) print(f'Employees with EmpID: {ref[0][0]} and {ref[1][0]} worked together on Project ID: {job} for {dd} days') except ValueError: print(f"日期格式错误,跳过Project {job}中的员工组合{ref[0][0]}和{ref[1][0]}") # 找出共事最久的员工组合 if collaboration_days: max_days = max(collaboration_days, key=lambda x: x[3]) print("\n共事时长最久的员工组合:") print(f"员工{max_days[0]}和{max_days[1]},在项目{max_days[2]}中共事了{max_days[3]}天") else: print("没有找到有效共事的员工组合")
关键修改点:
- 提前生成格式化的当日日期字符串,避免重复计算
- 读取每行时兼容'NULL'的大小写和前后空格情况
- 新增结果存储和最终筛选最长共事组合的逻辑,完成核心任务
- 添加日期格式异常捕获,提升代码健壮性
二、Pandas完整解决方案
你的原有Pandas代码已经完成了一部分,这里补全处理'NULL'的逻辑,以及最终找出共事最久员工的步骤:
import pandas as pd import datetime as dt # 读取CSV,将'NULL'识别为NaN并自动解析日期列 df = pd.read_csv( 'data.csv', delimiter=',', na_values=['NULL'], parse_dates=['DateFrom', 'DateTo'] ) # 将DateTo为NaN的行替换为当日日期 today = dt.date.today() df['DateTo'] = df['DateTo'].fillna(pd.to_datetime(today)) # 按项目分组,计算所有员工组合的共事时长 collaboration = [] for proj_id, group in df.groupby('ProjectID'): if len(group) >= 2: # 生成项目内的所有员工组合 for i in range(len(group)): for j in range(i+1, len(group)): emp1 = group.iloc[i] emp2 = group.iloc[j] # 计算共事的时间区间 start = max(emp1['DateFrom'], emp2['DateFrom']) end = min(emp1['DateTo'], emp2['DateTo']) if start < end: days = (end - start).days collaboration.append({ 'EmpID1': emp1['EmpID'], 'EmpID2': emp2['EmpID'], 'ProjectID': proj_id, 'CollabDays': days }) # 转换为DataFrame并找出最长共事组合 collab_df = pd.DataFrame(collaboration) if not collab_df.empty: max_collab = collab_df.loc[collab_df['CollabDays'].idxmax()] print("共事时长最久的员工组合:") print(f"员工{max_collab['EmpID1']}和{max_collab['EmpID2']},在项目{max_collab['ProjectID']}中共事了{max_collab['CollabDays']}天") else: print("没有找到有效共事的员工组合") # 可选:打印所有有效共事组合 print("\n所有有效共事组合:") print(collab_df)
关键优化:
- 使用
na_values=['NULL']直接将CSV中的'NULL'识别为Pandas的NaN值 - 用
fillna()快速批量替换所有缺失的DateTo为当日日期 - 按项目分组生成员工组合,通过Pandas的日期运算简化时长计算
- 用
idxmax()快速定位最长共事时长的组合,代码更简洁高效
内容的提问来源于stack exchange,提问作者Gergan Zhekov
相关产品推荐
相关产品推荐

