Python中按条件计算员工工时及ValueError报错解决求助
解决员工工时计算的ValueError问题
咱们一步步来搞定你遇到的这个报错问题,先拆解下错误根源,再给出修正后的完整代码:
报错原因分析
你碰到的ValueError主要是由这几个代码问题导致的:
- 错误的时间转换逻辑:你直接对完整的
datetime类型字段用pd.to_timedelta(),这肯定不行——pd.to_timedelta()没法直接把带日期的datetime对象转成时间差,得先提取里面的时间部分再转换。 - 变量名写错了:
elif分支里用了t['In Punch'],但你的函数参数明明是df,这里应该改成df['In Punch']。 - 逻辑运算符用错:条件判断里用了
|(按位或),多个条件同时满足的话应该用&(逻辑与)。 - 缺少返回值:函数的
else分支只算了时间差,但没写return返回结果,这会导致程序不知道该返回什么。 - 日期格式解析问题:你的原始数据里同时有
YYYY-MM-DD和DD-MM-YYYY两种日期格式,直接用pd.to_datetime()会把30-07-2019这种格式解析错(会当成30月7日),得加dayfirst=True来告诉程序日在前。
修正后的完整代码
import pandas as pd # 原始数据 df = pd.DataFrame({ 'ID':[1001,1002,1003,1004,1005,1006], 'In Punch':['2019-07-28 08:27:25','30-07-2019 08:10:56','05-08-2019 19:44:12','06-08-2019 08:28:51','25-08-2019 08:03:50','08-08-2019 12:44:12'], 'Out Punch':['2019-07-28 08:27:25','30-07-2019 19:48:28','05-08-2019 19:44:12','06-08-2019 19:47:21','25-08-2019 19:40:05','08-08-2019 12:44:12'] }) # 正确解析日期:指定dayfirst=True处理DD-MM-YYYY格式 df['In Punch'] = pd.to_datetime(df['In Punch'], dayfirst=True) df['Out Punch'] = pd.to_datetime(df['Out Punch'], dayfirst=True) def calculate_hours(row): time_diff = row['Out Punch'] - row['In Punch'] # 检查时间差是否为0 if time_diff == pd.Timedelta(0): # 提取In Punch的时间部分转为timedelta in_time = pd.to_timedelta(row['In Punch'].time().strftime('%H:%M:%S')) if in_time <= pd.Timedelta(12, unit='H'): return pd.Timedelta(8, unit='H') # 12点之后的所有情况都返回4小时,不用额外分支 else: return pd.Timedelta(4, unit='H') else: return time_diff # 应用函数生成Hours列 df['Hours'] = df.apply(calculate_hours, axis=1) print(df)
代码细节说明
- 日期解析优化:加了
dayfirst=True,确保30-07-2019这类日在前的日期被正确识别为2019年7月30日,避免解析错误。 - 时间提取与转换:用
row['In Punch'].time()把datetime里的时间单独提出来,转成字符串后再用pd.to_timedelta()转换,这样就能和12小时的时间差正确比较了。 - 简化逻辑:根据你的规则,12点之后(不管是12-14点还是14点之后)都返回4小时,所以直接用else覆盖所有12点后的情况就行,不用写复杂的elif分支。
- 明确返回值:所有分支都加了
return,确保每个情况都有返回结果,不会出现无返回值的错误。
运行结果
ID In Punch Out Punch Hours 0 1001 2019-07-28 08:27:25 2019-07-28 08:27:25 08:00:00 1 1002 2019-07-30 08:10:56 2019-07-30 19:48:28 11:37:32 2 1003 2019-08-05 19:44:12 2019-08-05 19:44:12 04:00:00 3 1004 2019-08-06 08:28:51 2019-08-06 19:47:21 11:18:30 4 1005 2019-08-25 08:03:50 2019-08-25 19:40:05 11:36:15 5 1006 2019-08-08 12:44:12 2019-08-08 12:44:12 04:00:00
内容的提问来源于stack exchange,提问作者Andre_k
相关产品推荐
相关产品推荐

