基于DataFrame订单分组的工作日逆向推算工序起止日期问题
订单工序日期逆向计算方案
我们有一个包含多组订单的Pandas DataFrame,每组订单包含多个工序,每个工序对应LeadTime(工作日前置时间)。每组订单的最后一道工序已知起止日期(该工序LeadTime为0,起止日期一致)。需要为每组订单的前置工序逆向计算起止日期,规则如下:
- 某工序的Finish日期 = 下一道工序的Start日期(仅同订单组内生效)
- LeadTime按工作日计算,且工序的Start日期必须为工作日
初始DataFrame结构
Order Process LeadTime Start Finish 01 A 3 NaT NaT 01 B 5 NaT NaT 01 C 0 2023-11-30 2023-11-30 02 D 2 NaT NaT 02 E 0 2023-12-13 2023-11-13 03 F 1 NaT NaT 03 G 1 NaT NaT 03 H 6 NaT NaT 03 I 0 2023-11-21 2023-11-21 ... ... ... ... ...
期望输出
Order Process LeadTime Start Finish 01 A 3 2023-11-20 2023-11-23 01 B 5 2023-11-23 2023-11-30 01 C 0 2023-11-30 2023-11-30 02 D 2 2023-12-08 2023-12-12 02 E 0 2023-12-12 2023-12-12 03 F 1 2023-11-09 2023-11-10 03 G 1 2023-11-10 2023-11-13 03 H 6 2023-11-13 2023-11-21 03 I 0 2023-11-21 2023-11-21 ... ... ... ... ...
实现方案
依赖工具
需要用到pandas和pandas.tseries.offsets中的CustomBusinessDay(默认不含周末,如需自定义节假日可扩展)。
代码实现
import pandas as pd from pandas.tseries.offsets import CustomBusinessDay # 1. 数据预处理:转换日期格式,每组订单逆序排列(从最终工序往前计算) df['Start'] = pd.to_datetime(df['Start']) df['Finish'] = pd.to_datetime(df['Finish']) # 按订单分组,每组内工序逆序(假设原数据工序为执行正序) df = df.groupby('Order', group_keys=False).apply(lambda x: x.iloc[::-1].reset_index(drop=True)) # 2. 定义工作日偏移规则 bd = CustomBusinessDay() # 3. 逆向计算各工序起止日期 for idx in range(1, len(df)): if df.iloc[idx]['Order'] == df.iloc[idx-1]['Order']: # 当前工序Finish日期 = 下一道工序的Start日期 current_finish = df.iloc[idx-1]['Start'] df.loc[df.index[idx], 'Finish'] = current_finish # 计算Start日期:往前推LeadTime个工作日 lead_time = df.iloc[idx]['LeadTime'] current_start = current_finish - lead_time * bd # 额外校验确保Start为工作日(理论上无需,但做冗余处理) if current_start.weekday() >= 5: current_start = current_start - bd * (current_start.weekday() - 4) df.loc[df.index[idx], 'Start'] = current_start # 4. 恢复每组订单的工序正序 df = df.groupby('Order', group_keys=False).apply(lambda x: x.iloc[::-1].reset_index(drop=True)) # 输出结果 print(df)
代码说明
- 预处理:转换日期列格式并将每组订单工序逆序,确保从已知的最终工序开始逆向推导。
- 工作日偏移:
CustomBusinessDay默认排除周末,如需加入法定节假日,可在初始化时传入holidays参数,例如CustomBusinessDay(holidays=[pd.to_datetime('2023-12-25')])。 - 逆向计算:遍历逆序后的订单组,按规则依次推导前置工序的起止日期。
- 恢复正序:计算完成后将每组工序恢复为原执行顺序。
内容的提问来源于stack exchange,提问作者Prmake
相关产品推荐
相关产品推荐

