You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何合并DataFrame中连续及跨周末的年假记录并设置合并阈值?

解决年假记录合并问题的方案

核心思路

不再逐行更新字段,而是按员工分组后,将所有属于同一可合并区间的记录归为一组,最后一次性聚合,这样能完美处理连续多行单日休假的情况,同时支持自定义合并阈值。

步骤实现

1. 数据预处理

先确保日期列是datetime类型,并按员工ID和休假开始日期排序:

import pandas as pd
import numpy as np

# 假设你的原始数据是df
df['StartDate'] = pd.to_datetime(df['StartDate'])
df['EndDate'] = pd.to_datetime(df['EndDate'])
df = df.sort_values(['员工ID', 'StartDate']).reset_index(drop=True)

2. 标记可合并的记录

按员工分组,判断当前行是否需要与上一行合并,覆盖你提到的两类场景+自定义阈值:

# 定义合并条件:
# - 连续单日休假(当前开始日 = 上一行结束日+1)
# - 周五结束后接周一休假(间隔2天,且上一行结束日是周五,当前开始日是周一)
# - 自定义间隔阈值(比如间隔<3天,可改为5等)
df['merge_flag'] = df.groupby('员工ID').apply(
    lambda x: (
        (x['StartDate'] == x['EndDate'].shift(1) + pd.Timedelta(days=1)) |
        ((x['StartDate'] == x['EndDate'].shift(1) + pd.Timedelta(days=2)) & 
         (x['EndDate'].shift(1).dt.weekday == 4) &  # 周五的weekday是4(周一=0,周日=6)
         (x['StartDate'].dt.weekday == 0)) |
        ((x['StartDate'] - x['EndDate'].shift(1)).dt.days < 3)  # 这里的3是自定义阈值,按需修改
    )
).reset_index(drop=True)

# 第一行没有上一行,标记为False
df['merge_flag'] = df['merge_flag'].fillna(False)

3. 生成合并组ID

通过反向标记(不需要合并的行为新组起点),用累计求和生成唯一组ID:

# 每遇到不需要合并的行,组ID加1
df['group_id'] = (~df['merge_flag']).cumsum()

4. 聚合合并结果

按员工ID和组ID聚合,取最早的开始日、最晚的结束日,累加工作日:

merged_df = df.groupby(['员工ID', 'group_id']).agg(
    StartDate=('StartDate', 'min'),
    EndDate=('EndDate', 'max'),
    WorkingDays=('WorkingDays', 'sum')
).reset_index(drop=True)

为什么之前的方法失效?

你之前用np.where逐行更新字段,只能处理相邻两行的合并,无法覆盖连续3行及以上的场景(比如3个单日休假,第一次合并前两行后,第三行无法关联到合并后的行)。而分组聚合的方式,会把所有属于同一合并区间的记录归为一组,一次性完成合并,也无需手动删除已合并行。

自定义阈值调整

如果需要将合并阈值改为间隔小于5天,只需把代码中(x['StartDate'] - x['EndDate'].shift(1)).dt.days < 3的3改成5即可。如果要按工作日间隔判断(忽略周末),可以用np.busday_count计算工作日差:

# 替换之前的间隔计算逻辑为工作日间隔
df['workday_diff'] = df.groupby('员工ID').apply(
    lambda x: np.busday_count(x['EndDate'].shift(1).dt.date, x['StartDate'].dt.date)
).reset_index(drop=True)

# 合并条件改为工作日间隔<2(即中间无工作日)
df['merge_flag'] = df.groupby('员工ID').apply(
    lambda x: (x['workday_diff'] == 0)
).reset_index(drop=True)

内容的提问来源于stack exchange,提问作者mzietal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 13:05:41