You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于缓存规则的DataFrame去重:按ID与日期规则清理重复行

Pandas按ID和日期规则去重:保留非基准日/次日的行

问题描述

我有一个包含ID和Datetime两列的DataFrame,需要根据Datetime列对同一ID的行进行筛选去重。规则为:以某一行的日期为基准,后续行若日期是基准日当天或次日23:59:59之前,则删除该行;找到第一个不在此范围的行作为新基准,重复此逻辑。

原始DataFrame

IDDatetime
1002023-05-01 10:00:00
1002023-05-01 11:00:00
1002023-05-01 15:00:00
1002023-05-02 17:00:00
1002023-05-02 23:59:59
1002023-05-03 01:00:00
1002023-05-03 05:00:00
2002023-05-01 15:00:00
2002023-05-01 18:00:00
2002023-05-02 12:00:00
2002023-05-03 07:00:00

预期结果

IDDatetime
1002023-05-01 10:00:00
1002023-05-03 01:00:00
2002023-05-01 15:00:00
2002023-05-03 07:00:00

我尝试过移位行、计算时间差的方法,但没解决问题。


解决方案

核心思路

按ID分组后,迭代确定保留的基准行:

  1. 先将Datetime列转为datetime类型,保证时间运算的准确性
  2. 对每个ID的时间序列排序(避免原始数据顺序混乱导致逻辑错误)
  3. 从第一个行开始标记为保留,跳过所有在基准日当天或次日23:59:59之前的行,找到下一个符合条件的行作为新基准,重复此过程

代码实现

import pandas as pd

# 构造原始数据
data = {
    'ID': [100,100,100,100,100,100,100,200,200,200,200],
    'Datetime': ['2023-05-01 10:00:00','2023-05-01 11:00:00','2023-05-01 15:00:00',
                 '2023-05-02 17:00:00','2023-05-02 23:59:59','2023-05-03 01:00:00',
                 '2023-05-03 05:00:00','2023-05-01 15:00:00','2023-05-01 18:00:00',
                 '2023-05-02 12:00:00','2023-05-03 07:00:00']
}
df = pd.DataFrame(data)

# 转换为datetime类型
df['Datetime'] = pd.to_datetime(df['Datetime'])

# 按ID和时间排序,确保时间顺序正确
df = df.sort_values(['ID', 'Datetime']).reset_index(drop=True)

# 定义分组筛选函数
def filter_group(group):
    keep_indices = []
    current_idx = 0
    n = len(group)
    while current_idx < n:
        # 保留当前基准行
        keep_indices.append(current_idx)
        # 计算截止时间:基准日次日的23:59:59
        base_date = group.iloc[current_idx]['Datetime'].date()
        cutoff_time = pd.Timestamp(base_date + pd.Timedelta(days=1)) + pd.Timedelta(hours=23, minutes=59, seconds=59)
        # 找到第一个超出截止时间的行索引
        next_idx = current_idx + 1
        while next_idx < n and group.iloc[next_idx]['Datetime'] <= cutoff_time:
            next_idx += 1
        current_idx = next_idx
    return group.iloc[keep_indices]

# 分组应用筛选逻辑
result_df = df.groupby('ID', group_keys=False).apply(filter_group)

print(result_df)

代码说明

  • 时间类型转换:确保Datetime列可以进行时间比较和运算
  • 排序处理:保证每个ID下的时间是按先后顺序排列的,避免筛选逻辑出错
  • 迭代筛选:通过循环逐个确定基准行,跳过所有符合删除条件的行,直到遍历完当前ID的所有行
  • 分组应用:对每个ID独立执行筛选逻辑,最后合并结果得到目标DataFrame

内容的提问来源于stack exchange,提问作者Leonardo Vieira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:42:14