Pandas:删除出现在时间间隔 pandas 内的重复项

Pandas: Drop duplicates that appear within a time interval pandas

我们有一个包含 'ID' 和 'DAY' 列的数据框,显示特定客户何时提出投诉。我们需要从 'ID' 列中删除重复项,但前提是重复项相隔 30 天。请看下面的例子:

当前数据集:

   ID        DAY           
0   1  22.03.2020       
1   1  18.04.2020       
2   2  10.05.2020       
3   2  13.01.2020       
4   3  30.03.2020       
5   3  31.03.2020       
6   3  24.02.2021 

目标:

   ID     DAY           
0   1  22.03.2020       
1   2  10.05.2020       
2   2  13.01.2020       
3   3  30.03.2020       
4   3  24.02.2021      

有什么建议吗?我试过 groupby 然后创建一个循环来计算每个组合之间的差异,但是因为数据框有数百万行这将永远...

您可以尝试按 ID 列和 diff 每个组中的 DAY 列进行分组

df['DAY'] = pd.to_datetime(df['DAY'], dayfirst=True)

from datetime import timedelta

m = timedelta(days=30)

out = df.groupby('ID').apply(lambda group: group[~group['DAY'].diff().abs().le(m)]).reset_index(drop=True)
print(out)

   ID        DAY
0   1 2020-03-22
1   2 2020-05-10
2   2 2020-01-13
3   3 2020-03-30
4   3 2021-02-24

要转换为原始日期格式,您可以使用dt.strftime

out['DAY'] = out['DAY'].dt.strftime('%d.%m.%Y')
print(out)

   ID         DAY
0   1  22.03.2020
1   2  10.05.2020
2   2  13.01.2020
3   3  30.03.2020
4   3  24.02.2021

您可以计算每组连续日期之间的差异,并使用它来形成一个掩码以删除间隔少于 30 天的日期:

df['DAY'] = pd.to_datetime(df['DAY'], dayfirst=True)

mask = (df
        .sort_values(by=['ID', 'DAY'])
        .groupby('ID')['DAY']
        .diff().lt('30d')
        .sort_index()
       )

df[~mask]

注意。这种方法的潜在缺点是,如果客户在 30 天内提出新的投诉,这将重新启动下一次投诉的阈值

输出:

   ID        DAY
0   1 2020-03-22
2   2 2020-10-05
3   2 2020-01-13
4   3 2020-03-30
6   3 2021-02-24

因此,另一种方法可能是 resample 每组数据到 30 天:

(df
 .groupby('ID')
 .resample('30d', on='DAY').first()
 .dropna()
 .convert_dtypes()
 .reset_index(drop=True)
)

输出:

   ID        DAY
0   1 2020-03-22
1   2 2020-01-13
2   2 2020-10-05
3   3 2020-03-30
4   3 2021-02-24