基于业务日的按组带条件反向累积起始日期计算
按组反向计算工作日起始日期(保留已有有效日期)
原始DataFrame
Group LT Start 0 A 5 NaT 1 A 10 NaT 2 A 0 20-03-2024 3 B 3 NaT 4 B 0 04-03-2024 5 C 2 NaT 6 C 4 NaT 7 C 0 04-04-2024 8 C 0 10-04-2024 9 C 0 24-04-2024
需求说明
- 按
Group列分组,对Start为NaT的行从下往上计算起始日期 - 以组内首个非NaT的Start值(从下往上数第一个有效日期)作为反向累积计算的起点,组切换时停止计算
LT代表工作日,计算时需跳过周末- 必须保留已有有效
Start值(此类行的LT值无效) - 每组最后一行必有有效
Start日期,因此必有计算起点
期望输出
Group LT Start 0 A 5 28-02-2024 1 A 10 06-03-2024 2 A 0 20-03-2024 3 B 3 28-02-2024 4 B 0 04-03-2024 5 C 2 27-03-2024 6 C 4 29-03-2024 7 C 0 04-04-2024 8 C 0 10-04-2024 9 C 0 24-04-2024
已尝试的代码及问题
尝试1:按组筛选NaT行但未跳过周末
groups = df.groupby('Group') nan_start_mask = df['Start'].isna() df['Start'] = groups['Start'].bfill() start_date = df['Start'] - pd.to_timedelta(df['LT'], unit='D') df.loc[nan_start_mask, 'Start'] = start_date[nan_start_mask]
问题:直接用自然日减法,未跳过周末,不符合LT为工作日的要求。
尝试2:支持工作日计算但覆盖有效日期
s = (df.loc[::-1, 'LT'].groupby(df['Group']).cumsum().apply(pd.offsets.BusinessDay)) g = df.groupby('Group') df['Start'] = pd.to_datetime(g['Start'].transform('first').sub(s))
问题:覆盖所有已有有效Start值,仅保留每组最后一行的计算结果,违反保留原始有效日期的需求。
解决方案
代码实现
import pandas as pd # 转换Start列为datetime类型,确保日期格式正确 df['Start'] = pd.to_datetime(df['Start'], format='%d-%m-%Y') def fill_group_dates(group): # 反转组内顺序,从下往上处理 reversed_group = group.iloc[::-1].copy() cum_workdays = 0 last_valid_date = None for idx, row in reversed_group.iterrows(): if pd.notna(row['Start']): # 记录当前有效日期,重置累积工作日偏移 last_valid_date = row['Start'] cum_workdays = 0 else: # 累积工作日,计算当前行的起始日期 cum_workdays += row['LT'] reversed_group.loc[idx, 'Start'] = last_valid_date - pd.offsets.BusinessDay(cum_workdays) # 反转回原顺序返回 return reversed_group.iloc[::-1] # 按Group分组处理,保留原始索引 df = df.groupby('Group', group_keys=False).apply(fill_group_dates) # 格式化日期为原有的dd-mm-YYYY格式 df['Start'] = df['Start'].dt.strftime('%d-%m-%Y') print(df)
思路说明
- 日期类型转换:先将
Start列转为datetime类型,避免字符串格式导致的计算错误 - 组内反向遍历:对每个组反转行顺序,从下往上处理,确保以首个有效日期(从下数)为计算起点
- 累积工作日计算:仅对
NaT行累积LT值,用最近的有效日期减去累积工作日偏移(自动跳过周末) - 保留有效日期:遇到有效日期时重置累积偏移,不修改原始有效日期
- 格式还原:计算完成后将日期转回原字符串格式
内容的提问来源于stack exchange,提问作者Prmake
相关产品推荐
相关产品推荐

