【问题标题】:Adjust the overlapping dates in group by with priority from another columns以其他列的优先级调整 group by 中的重叠日期
【发布时间】:2020-06-15 03:01:29
【问题描述】:

正如标题建议的那样,我正在解决一个问题,即根据 ID 查找重叠日期并根据优先级(重量)调整重叠日期。以下代码有助于找到重叠的日期。

df['overlap'] = (df.groupby('ID')
                   .apply(lambda x: (x['End_date'].shift() - x['Start_date']) > timedelta(0))
                   .reset_index(level=0, drop=True))
df

现在我面临的问题是,如何引入优先级(权重)并以此调整 start_date。在下图中,我突出显示了基于权重的调整日期,其中 A 优先于 B,B 优先于 C。

我应该为字符串到数字权重值创建一个字典,然后呢?我被困在这里设置逻辑。

数据框:

op_d = {'ID': [1,1,1,2,2,3,3,3],'Start_date':['9/1/2020','10/10/2020','11/18/2020','4/1/2015','5/12/2016','4/1/2015','5/15/2016','8/1/2018'],\
        'End_date':['10/9/2020','11/25/2020','12/31/2020','5/31/2016','12/31/2016','5/29/2016','9/25/2018','10/15/2020'],\
       'Weight':['A','B','C','A','B','A','B','C']}
df = pd.DataFrame(data=op_d)

【问题讨论】:

    标签: python-3.x pandas datetime


    【解决方案1】:

    您已经确定了重叠条件,然后您可以尝试在 End_Date 和班次中添加一天,然后将它们分配给重叠列为 true 的开始日期:

    arr = np.where(df['overlap'],df['End_date'].add(pd.Timedelta(1,unit='d')).shift(),
         df['Start_date'])
    out = df.assign(Output_Start_Date = arr,Output_End_Date=df['End_date'])
    

    print(out)
       ID Start_date   End_date Weight  overlap Output_Start_Date Output_End_Date
    0   1 2020-09-01 2020-10-09      A    False        2020-09-01      2020-10-09
    1   1 2020-10-10 2020-11-25      B    False        2020-10-10      2020-11-25
    2   1 2020-11-18 2020-12-31      C     True        2020-11-26      2020-12-31
    3   2 2015-04-01 2016-05-31      A    False        2015-04-01      2016-05-31
    4   2 2016-05-12 2016-12-31      B     True        2016-06-01      2016-12-31
    5   3 2015-04-01 2016-05-29      A    False        2015-04-01      2016-05-29
    6   3 2016-05-15 2018-09-25      B     True        2016-05-30      2018-09-25
    7   3 2018-08-01 2020-10-15      C     True        2018-09-26      2020-10-15
    

    【讨论】:

    • 考虑一个场景,其中行不按权重排序或权重具有不同的优先级,即上述数据框中的 B > A > C。在这种情况下,上面的代码将不起作用,必须查找重量或按重量顺序排序?
    • @Prish 是的,这是考虑对权重进行排序,如果您的优先顺序发生变化,您可以先将权重列转换为分类(如果您还没有)df['Weight'] = pd.Categorical(df['Weight'],categories=['B','A','C'],ordered=True),然后按IDWeight df=df.sort_values(['ID','Weight']) ,然后使用此代码
    • @Prish 或专门针对您的评论pd.Categorical(df['Weight'],categories=['C','A','B'],ordered=True) 给出[C < A < B]
    猜你喜欢
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-07
    相关资源
    最近更新 更多