【问题标题】:Validate dataframe duplicates using start and end date使用开始和结束日期验证数据框重复
【发布时间】:2020-06-26 12:37:37
【问题描述】:

我有以下员工数据框,以“PERSON_NUMBER”表示,他们在“ELEMENT_NAME”中享有的福利,直到它有效为止:

                       ELEMENT_NAME Element_Start_Date Element_End_Date
PERSON_NUMBER                                                          
3720081000         Standard Bonus M         2017-09-30       2025-12-31
3720081000            IE Healthcare         2016-12-01       2025-12-31
3720081000              IE Pensions         2016-09-01       2019-12-31
3720081000              IE Pensions         2019-09-01       2025-12-31
3720081000              IE Pensions         2020-03-01       2025-12-31
3720082294         IE Car Allowance         2020-03-09       2025-12-31
3720082295         Standard Bonus K         2020-03-23       2025-12-31
3720082305              IE Pensions         2020-05-25       2025-12-31
3720082305              IE Pensions         2017-05-25       2019-12-31
3720082395         Standard Bonus J         2020-03-23       2020-04-31
3720082395         Standard Bonus J         2020-05-25       2020-12-31
3720082395         Standard Bonus J         2020-09-25       2025-12-31

一个人的记录中可以有多个元素,但是对于每个唯一元素,我们不能在任何时间点在特定时间段内复制该元素。

案例 1:

因此,例如,在此数据框中,员工 3720081000 有 2 个第一奖金,但对于“IE PENSIONS”,您可以看到它第一次收到“IE PENSIONS”时,结束日期是“2019-12- 31”但下一行从“2019-09-01”开始具有相同的元素,这意味着从“2019 年 9 月到 2019 年 12 月”这个元素在他的记录中出现了两次。然后,该元素再次出现在第三条记录中。

案例 2:

但例如员工 3720082305 就可以了,因为虽然他们有两次“IE Pensions”,但开始日期和结束日期不会冲突。

案例 3:

对于员工 3720082295,您可以看到他们有 3 条“标准奖金 J”记录。第一条和第二条记录可以,因为收益从 Match 开始到 4 月,然后另一个从 5 月底开始,到 2025 年结束。但是,第三条记录是在 2020 年 9 月到 2025 年创建的,并且与之前的记录冲突为此人已开启此福利。

我希望得到所有相互冲突的行。

因此,该数据的预期输出将是:

                       ELEMENT_NAME Element_Start_Date Element_End_Date
PERSON_NUMBER                                                          
3720081000              IE Pensions         2016-09-01       2019-12-31
3720081000              IE Pensions         2019-09-01       2025-12-31
3720081000              IE Pensions         2020-03-01       2025-12-31
3720082395         Standard Bonus J         2020-05-25       2020-12-31
3720082395         Standard Bonus J         2020-09-25       2025-12-31

因此,如果员工编号在他们拥有的任何元素中出现任何错误,我想通过“PERSON NUMBER”返回该元素的所有行

构建此验证的最佳方式是什么?

【问题讨论】:

  • 你能show expecteddf吗?
  • @DanilaGanchar 重新解决了这个问题 :)

标签: python pandas date filter mask


【解决方案1】:

让我们从样本数据中的一个小修正开始:其中一个值 Element_End_Date 中为 2020-04-31,这不是任何有效日期 (四月只有30天),所以我把它改成了2020-04-30

我还假设:

  • Element_Start_DateElement_End_Date 都属于 datetime 类型(不是字符串)。
  • PERSON_NUMBERindex 列,如您的示例所示。

完成任务的准备步骤是定义一个函数来获取行 重叠的日期范围,对于每组行:

def getOverlapping(grp):
    ind = pd.IntervalIndex.from_arrays(grp.Element_Start_Date, grp.Element_End_Date)
    ovl = [ind.overlaps(x).sum() > 1 for x in ind]
    return grp[ovl]

为了得到结果,应用它:

df.set_index('ELEMENT_NAME', append=True).groupby(level=[0,1])\
    .apply(getOverlapping).reset_index(level=[2, 3], drop=True).reset_index(level=1)

结果是:

                   ELEMENT_NAME Element_Start_Date Element_End_Date
PERSON_NUMBER                                                      
3720081000          IE Pensions         2016-09-01       2019-12-31
3720081000          IE Pensions         2019-09-01       2025-12-31
3720081000          IE Pensions         2020-03-01       2025-12-31
3720082395     Standard Bonus J         2020-05-25       2020-12-31
3720082395     Standard Bonus J         2020-09-25       2025-12-31

【讨论】:

  • 非常感谢,这正是我所需要的!对不起“虚拟”虚拟数据哈哈
猜你喜欢
  • 2015-09-29
  • 1970-01-01
  • 2021-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-30
相关资源
最近更新 更多