pandas 同id日期非连续时仅保留较早记录的高效实现方法
同ID日期连续性校验的高效过滤方案
原逐行循环的实现存在两个核心问题:
- 数据量较大时,逐行遍历的性能远低于pandas向量化操作
- 代码存在变量名书写错误(误将
df写为date),仅打印了待删除的日期,未实际完成过滤逻辑
实现代码
import pandas as pd # 1. 转换日期格式,直接对整列操作比apply效率更高 df['date'] = pd.to_datetime(df['date']) # 2. 保存原始行顺序,用于后续还原原有排列 df['original_idx'] = df.index # 3. 按ID、日期升序排序,保证同ID行按日期从小到大排列 df_sorted = df.sort_values(['id', 'date']).reset_index(drop=True) # 4. 按ID分组,提取同ID下前一行的日期 df_sorted['prev_date'] = df_sorted.groupby('id')['date'].shift(1) # 5. 计算当前行与同ID前一行的日期差 df_sorted['date_gap'] = df_sorted['date'] - df_sorted['prev_date'] # 6. 筛选规则:同ID第一条记录直接保留,与前一行日期差≤1天的保留 keep_mask = df_sorted['prev_date'].isna() | (df_sorted['date_gap'] <= pd.Timedelta(days=1)) # 7. 过滤后还原原始行顺序,删除临时辅助列 df_final = ( df_sorted[keep_mask] .sort_values('original_idx') .drop(columns=['original_idx', 'prev_date', 'date_gap']) .reset_index(drop=True) )
效果验证
用示例数据执行后输出和期望结果完全一致:
date id 2020-12-11 A 2020-04-09 B 2020-04-09 C 2020-04-08 C 2021-03-11 D 2021-03-12 D 2021-01-19 E
如果不需要保留原始DataFrame的行顺序,可以跳过第2步和排序还原的逻辑,直接使用排序后的过滤结果即可。
内容的提问来源于stack exchange,提问作者tichy
相关产品推荐
相关产品推荐

