Sql 如果重复项意味着少于30天,我如何删除重复项?

Sql 如果重复项意味着少于30天,我如何删除重复项?,sql,pandas,Sql,Pandas,(使用sql或pandas) 如果两条记录之间的日期差小于30天,我想删除记录。 但必须保留ID的第一个记录 #example ROW ID DATE 1 A 2020-01-01 -- first 2 A 2020-01-03 3 A 2020-01-31 4 A 2020-02-05 5 A 2020-02-28 6 A 2020-03-09 7 B 2020-03-06 -- first 8 B

(使用sql或pandas) 如果两条记录之间的日期差小于30天,我想删除记录。 但必须保留ID的第一个记录

#example
ROW ID  DATE  
1   A   2020-01-01 -- first  
2   A   2020-01-03  
3   A   2020-01-31  
4   A   2020-02-05  
5   A   2020-02-28  
6   A   2020-03-09  
7   B   2020-03-06 -- first  
8   B   2020-05-07  
9   B   2020-06-02  

第2、3行在第1行起30天内 第5行在第4行之后的30天内 第9行在第8行之后的30天内

您可以尝试以下方法:

  • 将日期转换为
    datetime64
  • 从每个组中获取第一个日期
    df.groupby('ID')['date'].transform('first')
  • 添加筛选器以仅保留大于30天的日期
  • 将每个组的第一个日期附加到数据帧
  • 代码:

    df['DATE'] = pd.to_datetime(df['DATE'])
    
    df1 = df[(df['DATE'] - df.groupby('ID')['DATE'].transform('first')) >= pd.Timedelta(30, unit='D')]
    df1 = df1.append(df.groupby('ID', as_index=False).agg('first')).sort_values(by=['ID', 'DATE'])
    print(df1)
    
    
       ROW ID       DATE
    0    1  A 2020-01-01
    2    3  A 2020-01-31
    3    4  A 2020-02-05
    4    5  A 2020-02-28
    5    6  A 2020-03-09
    1    7  B 2020-03-06
    7    8  B 2020-05-07
    8    9  B 2020-06-02
    

    为了应付你的任务,你不可能打电话给任何人 矢量化方法

    原因是在一行被识别为重复行之后 当您进一步检查行时,此行“不计算”

    例如,删除第2020-01-03行和第2020-01-31行后(如图所示) “太接近”前一行)则2020-02-05行应为 左侧,因为现在到上一行的距离(2020-01-01) 足够大了

    因此,我提出了一个基于“带内存的函数”的解决方案:

    要获得预期结果,请运行:

    df[~(df.groupby('ID').apply(isDuplGrp).reset_index(level=0, drop=True))]
    
    (您可以将其保存回df)

    结果是:

       ROW ID       DATE
    0    1  A 2020-01-01
    3    4  A 2020-02-05
    5    6  A 2020-03-09
    6    7  B 2020-03-06
    7    8  B 2020-05-07
    
    最后,请注意另一种解决方案: 它包含以下行:

    3    4  A 2020-02-05
    4    5  A 2020-02-28
    
    相隔仅23天,因此此解决方案是错误的

    这同样适用于行:

    5  A 2020-02-28
    6  A 2020-03-09
    

    与第一个日期或最近的日期相比,它们的时间也太近。

    差异?请使用您正在运行的数据库标记您的问题:mysql、oracle、sql server…?更好地解释比较日期的标准是什么。在目前的表格中,它是非常模糊的。第一个日期将是起点。若第二个日期在第一个日期后30天,那个么第二个日期将是新的起点。如果不是的话,那争吵应该被消除这正是我想要的,非常感谢
       ROW ID       DATE
    0    1  A 2020-01-01
    3    4  A 2020-02-05
    5    6  A 2020-03-09
    6    7  B 2020-03-06
    7    8  B 2020-05-07
    
    3    4  A 2020-02-05
    4    5  A 2020-02-28
    
    5  A 2020-02-28
    6  A 2020-03-09