我有以下数据框:
date_one date_two
2634 2018-05-22 None
2018 2017-06-22 2017-09-22
2706 2016-09-14 None
3018 2016-06-22 None
我要使用以下逻辑在日期date_two
栏中填写
如果date_two
列在该行中已经有一个值,则什么也不做
对于date_one
列中的第一行,请使用当前日期或date_two
列中的6个月(以较早者为准)填写date_one
列
对于其他所有行,请使用当前行上方行date_two
列中日期之前一天的日期填写day_one
列,或距{{1 }}日期在当前行中,以较早的日期为准
最终结果如下:
date_one
注意: date_one date_two
2634 2018-05-22 2018-11-18
2018 2017-06-22 2017-09-22
2706 2016-09-14 2017-03-13
3018 2016-06-22 2016-09-13
的最后一列包含2016-09-13,因为2016-09-13是该行上方的date_two
行中的日期的前一天(规则2)。感谢@WeNYoBen。
我尝试使用date_one
,但不确定如何访问上一行的值
答案 0 :(得分:1)
我假设两个日期列都是 DateTime 类型, 因此缺少的 date_two 值实际上是 NaT ,而不是 None :
date_one date_two
2634 2018-05-22 NaT
2018 2017-06-22 2017-09-22
2706 2016-09-14 NaT
3018 2016-06-22 NaT
从计算辅助列开始-上一行的 date_one :
df['date_one_prev'] = df.date_one.shift()
请注意,第一行 date_one_prev 是 NaT ,将很快使用。
然后定义要应用于每一行的函数:
def fn(row):
if pd.isna(row.date_one_prev): # First row
return min(row.date_one + pd.DateOffset(180),
pd.to_datetime('today'))
elif pd.isna(row.date_two): # NaT
return min(row.date_one + pd.DateOffset(180),
row.date_one_prev + pd.DateOffset(-1))
else: # date_two present
return row.date_two
并应用此功能进行实际处理:
df.date_two = df.apply(fn, axis=1)
剩下的唯一要做的就是删除辅助列:
df.drop(columns=['date_one_prev'], inplace=True)
注意:根据您的评论,我用的是 180天,而不是 6个月。