基于 pandas 中的组的循环反向工作日总和。数据帧

Looped reversed sum of business days based on groups in pandas.Dataframe

提问人:Prmake 提问时间:11/17/2023 更新时间:11/17/2023 访问量:26

问:

我有一个 DataFrame,其中一列中包含各种订单组。每个订单组都有多个流程,每个流程都有自己的提前期。对于每个订单组的最后一个工序,我有完成日期(和开始日期,因为最终工序的提前期始终为零)。

现在,对于每个订单组的每个前一个过程,我需要计算开始和完成日期。流程的完成日期始终等于下一个流程的开始日期(除非下一个流程是新订单组)。提前期代表工作日,因此开始日期应始终在工作日。

My 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
...     ...        ...        ...     ...

关于如何实现这一目标的任何建议?

蟒蛇 熊猫

评论


答:

0赞 mozway 11/17/2023 #1

您可以计算 LeadTime 的反向 groupby.cumsum,转换为 BusinessDay 偏移量,然后从参考日期中减去此值(使用 groupby.transform 传播:

cols = ['Start', 'Finish']

df[cols] = df[cols].apply(pd.to_datetime)

s = (df.loc[::-1, 'LeadTime']
       .groupby(df['Order']).cumsum()
       .apply(pd.offsets.BusinessDay)
    )
g = df.groupby('Order')

for c in cols:
    df[c] = pd.to_datetime(g[c].transform('first').sub(s))

输出:

   Order Process  LeadTime      Start     Finish
0      1       A         3 2023-11-20 2023-11-20
1      1       B         5 2023-11-23 2023-11-23
2      1       C         0 2023-11-30 2023-11-30
3      2       D         2 2023-12-11 2023-11-09
4      2       E         0 2023-12-13 2023-11-13
5      3       F         1 2023-11-09 2023-11-09
6      3       G         1 2023-11-10 2023-11-10
7      3       H         6 2023-11-13 2023-11-13
8      3       I         0 2023-11-21 2023-11-21