移动多个日期列的优雅方式 - Pandas

Elegant way to shift multiple date columns - Pandas

我有一个如下所示的数据框

df = pd.DataFrame({'person_id': [11,11,11,21,21],
                   'offset' :['-131 days','29 days','142 days','20 days','-200 days'],
                   'date_1': ['05/29/2017', '01/21/1997', '7/27/1989','01/01/2013','12/31/2016'],
                   'dis_date': ['05/29/2017', '01/24/1999', '7/22/1999','01/01/2015','12/31/1991'],
                   'vis_date':['05/29/2018', '01/27/1994', '7/29/2011','01/01/2018','12/31/2014']})
df['date_1'] = pd.to_datetime(df['date_1'])
df['dis_date'] = pd.to_datetime(df['dis_date'])
df['vis_date'] = pd.to_datetime(df['vis_date'])

我愿意shift all the dates of each subject based on his offset

虽然我的代码有效(信用 - 所以),但我正在寻找一种优雅的方法。你可以看到我几乎重复了同一行三次。

df['offset_to_shift'] = pd.to_timedelta(df['offset'],unit='d') 
#am trying to make the below lines elegant/efficient
df['shifted_date_1'] = df['date_1'] + df['offset_to_shift']    
df['shifted_dis_date'] = df['dis_date'] + df['offset_to_shift']
df['shifted_vis_date'] = df['vis_date'] + df['offset_to_shift']

我希望我的输出如下所示

使用,DataFrame.add along with DataFrame.add_prefix and DataFrame.join:

cols = ['date_1', 'dis_date', 'vis_date']
df = df.join(df[cols].add(df['offset_to_shift'], 0).add_prefix('shifted_'))

或者,也可以使用 pd.concat:

df = pd.concat([df, df[cols].add(df['offset_to_shift'], 0).add_prefix('shifted_')], axis=1)

或者,我们也可以直接将新的移位列分配给数据框:

df[['shifted_' + col for col in cols]] = df[cols].add(df['offset_to_shift'], 0)

结果:

# print(df)

   person_id     offset     date_1   dis_date   vis_date offset_to_shift shifted_date_1 shifted_dis_date shifted_vis_date
0         11  -131 days 2017-05-29 2017-05-29 2018-05-29       -131 days     2017-01-18       2017-01-18       2018-01-18
1         11    29 days 1997-01-21 1999-01-24 1994-01-27         29 days     1997-02-19       1999-02-22       1994-02-25
2         11   142 days 1989-07-27 1999-07-22 2011-07-29        142 days     1989-12-16       1999-12-11       2011-12-18
3         21    20 days 2013-01-01 2015-01-01 2018-01-01         20 days     2013-01-21       2015-01-21       2018-01-21
4         21  -200 days 2016-12-31 1991-12-31 2014-12-31       -200 days     2016-06-14       1991-06-14       2014-06-14