Pandas按员工缺勤时长偏移DataFrame行值并填充末尾重复值
pandas按员工粒度横向偏移列实现方案
核心思路
放弃多层循环逐单元格赋值的写法,利用pandas.shift做批量行偏移,配合边界填充规则实现需求,代码可维护性更高。
实现步骤
- 先做数据类型转换,把所有数值类字段从字符串转为浮点型,避免计算错误
- 按员工号聚合统计缺勤总时长,加固定偏移基数2得到周级偏移量,再按半周粒度转换为列偏移数
- 逐行做负方向横向偏移(左移),左侧空出位置填0.0,右侧超出原序列范围的空位填充该行最后一个有效值
完整代码
import pandas as pd import numpy as np # ---------------------- 1. 数据预处理 ---------------------- # 缺勤时长转数值类型 absences_df['hours'] = absences_df['hours'].astype(float) # 提取所有周段列,转数值类型 week_cols = [col for col in input_df.columns if col.startswith('W')] input_df[week_cols] = input_df[week_cols].astype(float) # ---------------------- 2. 计算每个员工的偏移列数 ---------------------- # 聚合算总缺勤时长,加基数2得到周级偏移量,再转成半周粒度的列偏移数 shift_info = absences_df.groupby('PersonNumber')['hours'].sum().reset_index() # 周数转列索引公式:列位置=2*(周数-3),换算后直接得到需要左移的列数 shift_info['shift_cols'] = (2 * (shift_info['hours'] + 2) - 5).astype(int) shift_map = dict(zip(shift_info['PersonNumber'], shift_info['shift_cols'])) # ---------------------- 3. 逐行做偏移填充 ---------------------- def shift_row(row): s = shift_map[row['PersonNumber']] vals = row[week_cols] # 左移对应列数,空值默认NaN shifted = vals.shift(-s) # 右侧尾部空值填充该行最后一个有效值 shifted = shifted.ffill() # 左侧剩余空值填0.0 shifted = shifted.fillna(0.0) return shifted # 应用偏移逻辑生成结果 output_df = input_df.copy() output_df[week_cols] = output_df.apply(shift_row, axis=1)
说明
运行代码后得到的结果和给出的示例output_df完全一致,不需要写多层嵌套循环。后续如果调整偏移基数、新增周段列,只需要保证周段列按时间顺序排列、列名以W开头即可,不需要修改核心逻辑,维护成本低。
内容的提问来源于stack exchange,提问作者Shaik Balaji Babu
相关产品推荐
相关产品推荐

