Python 根据前几行在数据框中填写日期

Python 根据前几行在数据框中填写日期,python,pandas,Python,Pandas,我有以下数据帧: 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\u two列: 如果date\u two列在该行中已有值,则不执行任何操作

我有以下数据帧:

         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\u two
列:

  • 如果
    date\u two
    列在该行中已有值,则不执行任何操作

  • 对于
    date\u one
    列的第一行,使用当前日期或
    date\u one
    列的6个月(以较早者为准)填写
    date\u two

  • 对于所有其他行,使用当前行上方行中日期前一天的日期或当前行中日期后6个月的日期(以较早者为准),填写
    date\u two

  • 最终结果如下所示:

             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
    
    注:
    date\u two
    的最后一列包含2016-09-13,因为2016-09-13是该行上方
    date\u one
    行中日期的前一天(规则2)。感谢@WeNYoBen


    我尝试使用
    iterrows
    ,但不确定如何访问前一行的值

    我假设两个日期列都是DateTime类型, 因此,缺少的date_两个值实际上是NaT,而不是None:

    从计算上一行的辅助列-日期开始:

    df['date_one_prev'] = df.date_one.shift()
    
    请注意,对于第一行date\u one\u 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个月。

    日期的最后一列为什么是2016-09-13?@WeNYoBen这是因为2016-09-13比该行上方的日期早一天。
    date\u one
    行请看第一行。日期为2018年5月22日,因此:1。当日为2019-05-20。2.自日期起6个月的日期为2018年11月22日。3.这两个日期的较早日期为2018年11月22日。那么,为什么预期产出中的日期二是2018年11月18日?我想,应该是2018-11-22(规则2)。@Valdi#Bo谢谢你指出这一点!,6个月,我指的是180天,因为有些月有31天,所以
    date\u two
    值与您认为的值不同
    df.drop(columns=['date_one_prev'], inplace=True)