使用Pandas groupby和shift计算员工最长连续带薪休假时长
计算员工最长连续带薪休假天数及筛选超长连续记录
没问题,我来一步步帮你搞定这个需求,用Pandas的groupby和diff就能轻松实现~
第一步:准备数据并转换日期格式
首先得把日期字符串转成Pandas能识别的datetime类型,不然没法计算日期差。先构造你的示例数据:
import pandas as pd data = { 'employee_id': [1,1,1,1,2,2,2,2,2], 'time_off_date': ['1/1/2017','1/2/2017','1/3/2017','5/1/2017','6/1/2017','9/5/2017','9/6/2017','9/7/2017','9/8/2017'] } df = pd.DataFrame(data) # 转换日期格式 df['time_off_date'] = pd.to_datetime(df['time_off_date']) # 确保数据按员工和日期排序(避免原始数据乱序导致错误) df = df.sort_values(['employee_id', 'time_off_date'])
第二步:标记连续休假的分组
接下来要给每个连续的休假段分配一个唯一的组ID。核心思路是:对每个员工的日期,计算当前日期和前一天的差值,如果差值不等于1天,就标记为一个新的连续组开始。
# 计算当前日期与前一天的天数差,判断是否为新的连续组 df['is_new_series'] = df.groupby('employee_id')['time_off_date'].diff().dt.days != 1 # 每个员工的第一条记录没有前一天,所以填充为True(作为第一个组的开始) df['is_new_series'] = df['is_new_series'].fillna(True) # 累加标记生成连续组ID df['series_id'] = df.groupby('employee_id')['is_new_series'].cumsum()
这时候df会新增两列:is_new_series标记是否是新组的起点,series_id则是每个连续休假段的唯一标识。
第三步:计算每位员工的最长连续休假天数
现在可以按员工和组ID分组,计算每个组的天数,再找出每个员工的最大值:
# 计算每个连续休假组的天数 series_days = df.groupby(['employee_id', 'series_id']).size().reset_index(name='continuous_days') # 提取每个员工的最长连续休假天数 max_continuous_days = series_days.groupby('employee_id')['continuous_days'].max().reset_index(name='max_continuous_days') print(max_continuous_days)
运行后输出就是你要的结果:
employee_id max_continuous_days 0 1 3 1 2 4
第四步:筛选休假时长超过X天的连续记录
针对额外需求,只需要先筛选出天数超过X的组,再把这些组的原始记录关联回来就行。比如X=3:
X = 3 # 筛选出天数超过X的连续组 filtered_groups = series_days[series_days['continuous_days'] > X] # 关联回原始数据,得到所有符合条件的休假记录 long_leave_records = df.merge(filtered_groups, on=['employee_id', 'series_id']) print(long_leave_records)
输出就是员工2那4天的连续休假记录:
employee_id time_off_date is_new_series series_id continuous_days 0 2 2017-09-05 True 2 4 1 2 2017-09-06 False 2 4 2 2 2017-09-07 False 2 4 3 2 2017-09-08 False 2 4
小提示
如果你的原始数据日期可能存在乱序的情况,一定要先执行sort_values排序,不然diff计算出来的差值会出错,导致连续组标记错误哦~
内容的提问来源于stack exchange,提问作者NickBraunagel
相关产品推荐
相关产品推荐

