DataFrame计算出现NaN及合并结果不匹配的问题求解
问题修复方案
问题1:生成结果DataFrame时的错误(含潜在NaN风险)
你的calculate_days_and_overtime函数存在两个致命逻辑错误:
- 双重嵌套的
iterrows循环:导致每个员工的记录被重复处理多次,最终生成的结果行数远多于原数据 - return语句位置错误:return放在了外层循环的内部,函数仅处理完第一个员工的第一次循环就返回,后续员工完全未被处理
这两个错误会导致结果DataFrame数据重复、缺失,后续合并时极易出现NaN值。
问题2:合并DataFrame时数据不匹配
你使用pd.concat([df, results_df], ignore_index=True)是上下拼接两个DataFrame,而非按员工对应关系横向合并列,自然会出现数据错位的情况。
修复后的完整代码
import pandas as pd data = { 'Employee_ID': [1, 2, 3, 4, 5], 'Employment_Type': ['Remote', 'In-Office', 'Remote', 'Remote', 'Remote'], 'Hours_Worked_Per_Week': [29.0, 45.0, 34.0, 25.0, 50.0] } df = pd.DataFrame(data) def calculate_days_and_overtime(df): results = [] # 移除内层重复的iterrows循环 for index, row in df.iterrows(): total_hours = row['Hours_Worked_Per_Week'] regular_hours_per_day = 8 days_per_week = 5 total_regular_hours = days_per_week * regular_hours_per_day overtime = max(0, total_hours - total_regular_hours) regular_days = min(days_per_week, total_hours // regular_hours_per_day) # 原代码中修改total_hours无实际作用,可删除该步骤 # total_hours -= regular_days * regular_hours_per_day overtime_days = overtime // regular_hours_per_day remaining_overtime_hours = overtime % regular_hours_per_day total_days_worked = regular_days + overtime_days + (1 if remaining_overtime_hours else 0) results.append({ 'Employee_ID' : row['Employee_ID'], 'Regular Days' : regular_days, 'Overtime Days' : overtime_days, 'Remaining Overtime Hours' : remaining_overtime_hours, 'Total Days Worked' : total_days_worked, 'Work Location' : row['Employment_Type'] }) # 将return移到循环外部,确保所有员工都被处理 return pd.DataFrame(results) results_df = calculate_days_and_overtime(df) # 按Employee_ID进行横向合并,确保数据对应匹配 merged_df = pd.merge(df, results_df, on='Employee_ID', how='left') print(merged_df)
关键修复点说明
- 移除双重循环:确保每个员工仅被处理一次,结果行数与原数据一致
- 调整return位置:让函数遍历完所有员工后再返回结果DataFrame
- 正确合并方式:
- 使用
pd.merge按Employee_ID关联,确保每个员工的计算指标与原数据精准匹配 - 也可以选择直接在原DataFrame上计算新增列(更高效,避免额外的合并步骤),示例如下:
# 直接在原df上计算列的高效写法 df['Total Regular Hours'] = 5*8 df['Overtime'] = df['Hours_Worked_Per_Week'].apply(lambda x: max(0, x-40)) df['Regular Days'] = df['Hours_Worked_Per_Week'].apply(lambda x: min(5, x//8)) df['Overtime Days'] = df['Overtime'].apply(lambda x: x//8) df['Remaining Overtime Hours'] = df['Overtime'].apply(lambda x: x%8) df['Total Days Worked'] = df.apply(lambda row: row['Regular Days'] + row['Overtime Days'] + (1 if row['Remaining Overtime Hours'] else 0), axis=1) df['Work Location'] = df['Employment_Type']
- 使用
内容的提问来源于stack exchange,提问作者Arsenio Munnick
相关产品推荐
相关产品推荐

