根据组的第一个日期将月份累积添加到日期列

Cumulatively add month to a Date column based off the first date of a group

我有一个数据框,我试图根据将 DateTime 添加 3 个月的条件添加新列。

ID1    ID2          Date
 1     20    5/15/2019  11:06:47 AM
 1     21    5/15/2019  11:06:47 AM
 1     22    6/15/2019  11:06:47 AM
 2     30    7/15/2019  11:06:47 AM
 2     31    7/15/2019  11:06:47 AM
 2     32    7/15/2019  11:06:47 AM

需要输出,

ID1    ID2          Date                   NewDate
 1     20    5/15/2019 11:06:47 AM    8/15/2019 11:06:47 AM
 1     21    5/15/2019 11:06:47 AM    9/15/2019 11:06:47 AM
 1     22    6/15/2019 11:06:47 AM    10/15/2019 11:06:47 AM
 2     30    7/15/2019 11:06:47 AM    10/15/2019 11:06:47 AM
 2     31    7/15/2019 11:06:47 AM    11/15/2019 11:06:47 AM
 2     32    7/15/2019 11:06:47 AM    12/15/2019 11:06:47 AM

对于每个 ID1,只能有一个唯一的 NewDate。如果存在可能在同一月的日期,则添加另一个月。

对于具有不同日期的 ID1,如果 NewDate 落在与之前的 NewDate 相似的月份,那么我们添加另一个额外的 DateOffset,如所需输出的第 3 行所示

我试过下面的代码,

def add_date(df):
    for each_ID1 in df['ID1']:
        for each_ID2 in df['ID2']:
            return df['Date'] + DateOffset(months = 3)
    
df['New Date'] = df.apply(add_date, axis = 1)

我的代码只给出了 3 个月的 DateOffset,如图所示,

ID1    ID2          Date                   NewDate
 1     20    5/15/2019 11:06:47 AM    8/15/2019 11:06:47 AM
 1     21    5/15/2019 11:06:47 AM    8/15/2019 11:06:47 AM
 1     22    6/15/2019 11:06:47 AM    9/15/2019 11:06:47 AM
 2     30    7/15/2019 11:06:47 AM    10/15/2019 11:06:47 AM
 2     31    7/15/2019 11:06:47 AM    10/15/2019 11:06:47 AM
 2     32    7/15/2019 11:06:47 AM    10/15/2019 11:06:47 AM

输出错误

ID1    ID2          Date                   NewDate
 1     20    5/15/2019 11:06:47 AM    8/15/2019 11:06:47 AM
 1     21    5/15/2019 11:06:47 AM    9/15/2019 11:06:47 AM
 1     22    5/15/2019 11:06:47 AM    10/15/2019 11:06:47 AM
 1     23    5/15/2019 11:06:47 AM    11/15/2019 11:06:47 AM
 1     24    5/15/2019 11:06:47 AM    12/15/2020 11:06:47 AM
 1     25    5/15/2019 11:06:47 AM    01/15/2021 11:06:47 AM
 1     26    6/15/2019 11:06:47 AM    10/15/2019 11:06:47 AM
 1     27    6/15/2019 11:06:47 AM    12/15/2019 11:06:47 AM
 1     28    6/15/2019 11:06:47 AM    02/15/2020 11:06:47 AM
 1     29    6/15/2019 11:06:47 AM    04/15/2020 11:06:47 AM
 1     30    6/15/2019 11:06:47 AM    06/15/2020 11:06:47 AM
 1     31    6/15/2019 11:06:47 AM    07/15/2020 11:06:47 AM
  1. 您可以创建一个系列 m,在 ID1 列上使用 .groupby,return 每组的累计计数,然后加 3(因为这是方法您最初想要抵消很多个月)。使用 .cumcount(),组中每增加一行,偏移量就会增加 1。
  2. 然后,我们要创建 New Date 列,但只将 m 添加到每个组的第一个日期,因此我们在添加 m.values.astype("timedelta64[M]") 之前使用 df.groupby('ID1')['Date'].transform('first')

输入(您问题的最新编辑):

ID1    ID2          Date        
 1     20    5/15/2019 11:06:47 AM 
 1     21    5/15/2019 11:06:47 AM 
 1     22    5/15/2019 11:06:47 AM 
 1     23    5/15/2019 11:06:47 AM
 1     24    5/15/2019 11:06:47 AM
 1     25    5/15/2019 11:06:47 AM
 1     26    6/15/2019 11:06:47 AM 
 1     27    6/15/2019 11:06:47 AM 
 1     28    6/15/2019 11:06:47 AM 
 1     29    6/15/2019 11:06:47 AM  
 1     30    6/15/2019 11:06:47 AM 
 1     31    6/15/2019 11:06:47 AM

# df['Date'] = pd.to_datetime(df['Date'])
m = df.groupby('ID1').cumcount() + 3
df['New Date'] = df.groupby('ID1')['Date'].transform('first') + m.values.astype("timedelta64[M]")
df
Out[1]: 
    ID1  ID2                Date            New Date
0     1   20 2019-05-15 11:06:47 2019-08-14 18:34:05
1     1   21 2019-05-15 11:06:47 2019-09-14 05:03:11
2     1   22 2019-05-15 11:06:47 2019-10-14 15:32:17
3     1   23 2019-05-15 11:06:47 2019-11-14 02:01:23
4     1   24 2019-05-15 11:06:47 2019-12-14 12:30:29
5     1   25 2019-05-15 11:06:47 2020-01-13 22:59:35
6     1   26 2019-06-15 11:06:47 2020-02-13 09:28:41
7     1   27 2019-06-15 11:06:47 2020-03-14 19:57:47
8     1   28 2019-06-15 11:06:47 2020-04-14 06:26:53
9     1   29 2019-06-15 11:06:47 2020-05-14 16:55:59
10    1   30 2019-06-15 11:06:47 2020-06-14 03:25:05
11    1   31 2019-06-15 11:06:47 2020-07-14 13:54:11