【问题标题】:How drop duplicate rows based on a time delta whilst keep the latest occurrence of that record?如何根据时间增量删除重复行,同时保持该记录的最新出现?
【发布时间】:2021-08-30 12:22:40
【问题描述】:

我有一张表格:

ID DATE_ENCOUNTER LOAD
151336 2017-08-22 40
151336 2017-08-23 40
151336 2017-08-24 40
151336 2017-08-25 40
151336 2017-09-05 50
151336 2017-09-06 50
151336 2017-10-16 51
151336 2017-10-17 51
151336 2017-10-18 51
151336 2017-10-30 50
151336 2017-10-31 50
151336 2017-11-01 50
151336 2017-12-13 62
151336 2018-01-03 65
151336 2018-02-09 60

虽然日期不相同,但有些记录是重复的(仅在 4 天的增量内)。如果时间戳/日期接近(在 4 天的增量内),我如何在数据框中删除重复项(最早的记录)但是不相同。结果应显示如下表格:

ID DATE_ENCOUNTER LOAD
151336 2017-08-25 40
151336 2017-09-06 50
151336 2017-10-18 51
151336 2017-11-01 50
151336 2017-12-13 62
151336 2018-01-03 65
151336 2018-02-09 60

我试过了:

m = df.groupby('ID').DATE_ENCOUNTER.apply(lambda x: x.diff().dt.days < 4)
m2 = df.ID.duplicated(keep=false) & (m | m.shift(-1))
df_dedup2 = df[~m2]

下面是一些生成数据框的代码:

import pandas as pd
details = {
    'ID':[151336,151336,151336,151336,151336,151336,151336,151336,151336,151336,151336,151336,151336,151336,151336],
    'DATE_ENCOUNTER':['2017-08-22','2017-08-23','2017-08-24','2017-08-25','2017-09-05','2017-09-06','2017-10-16','2017-10-17','2017-10-18','2017-10-30','2017-10-31','2017-11-01','2017-12-13','2018-01-03','2018-02-09'],
    'LOAD':[40,40,40,40,50,50,51,51,51,50,50,50,62,65,60]
}
df=pd.DataFrame(details)

注意有更多的字段和更多的 ID。

【问题讨论】:

  • 为什么保留“2017-10-17”?
  • 同意,好像2017-10-17 与后续2017-10-18 仅相差1 天,不应保留
  • @Mazil_tov998 您的删除重复项是否也需要包含 LOAD 列?我的意思是,如果第一个日期的 LOAD 列是 30 而不是 40,你会删除它,因为日期在以下日期的 4 天内吗?

标签: python pandas dataframe filter duplicates


【解决方案1】:

你可以使用:

df[(df.groupby('ID')
      ['DATE_ENCOUNTER']
      .diff(-1).dt.days.mul(-1) # calculate the difference
      .fillna(float('inf'))     # make sure last row is kept
      .ge(4)                    # select diff >= 4
   )]

输出:

        ID DATE_ENCOUNTER  LOAD
3   151336     2017-08-25    40
5   151336     2017-09-06    50
8   151336     2017-10-18    51
11  151336     2017-11-01    50
12  151336     2017-12-13    62
13  151336     2018-01-03    65
14  151336     2018-02-09    60

【讨论】:

    【解决方案2】:

    你可以使用:

    #Convert to datetime format if not already in datetime
    #df['DATE_ENCOUNTER'] = pd.to_datetime(df['DATE_ENCOUNTER'])
    
    #Sort DATE_ENCOUNTER within the same ID if not already in this sequence
    #df = df.sort_values(by=['ID', 'DATE_ENCOUNTER'])
    
    # reuse your code of mask `m`
    m = df.groupby('ID').DATE_ENCOUNTER.apply(lambda x: x.diff().dt.days < 4)
    
    # set grouping of consecutive entries within 4 days difference within the same `ID` 
    g = (~m).groupby(df['ID']).cumsum()
    
    # pick the last entry in each group
    df.groupby(['ID', g], as_index=False).last()
    

    结果:

           ID DATE_ENCOUNTER  LOAD
    0  151336     2017-08-25    40
    1  151336     2017-09-06    50
    2  151336     2017-10-18    51
    3  151336     2017-11-01    50
    4  151336     2017-12-13    62
    5  151336     2018-01-03    65
    6  151336     2018-02-09    60
    

    【讨论】:

      猜你喜欢
      • 2020-12-19
      • 2011-08-31
      • 2021-09-12
      • 2011-05-10
      • 2019-12-20
      • 2019-08-04
      • 1970-01-01
      • 1970-01-01
      • 2020-04-05
      相关资源
      最近更新 更多