如何在Pandas DataFrame中检测间隔24小时的重复数据?
检测按ID分组后间隔24小时的重复数据
需求说明
现有从SQL查询得到的DataFrame,需按ID(每个ID对应唯一ID_Type)分组,检测该ID对应类型的数值列中,是否存在间隔恰好24小时的重复值,并通过布尔列标记。普通时间间隔的重复数据无需处理。
示例数据
import pandas as pd df = pd.DataFrame({ 'ID': [1, 3, 1, 2, 2, 2, 3, 1, 3, 4, 4, 5, 6, 7], 'ID_Type': ['A', 'C', 'A', 'B', 'B', 'B', 'C', 'A', 'C', 'A', 'A', 'B', 'C', 'C'], 'Type_A_Value': [10, None, 10, None, None, None, None, 30, None, 55, 40, None, None, None], 'Type_B_Value': [None, None, None, 10, 11, 26, None, None, None, None, None, 19, None, None], 'Type_C_Value': [None, 4.3, None, None, None, None, 89, None, 12.3, None, None, None, 27, 55], 'Datetime': ['2022-10-03 08:00:00', '2022-10-01 09:00:00', '2022-10-02 08:00:00', '2022-10-01 11:00:00', '2022-10-02 11:00:00', '2022-10-02 13:00:00', '2022-10-01 14:00:00', '2022-10-01 15:00:00', '2022-10-02 07:00:00', '2022-10-01 14:00:00', '2022-10-01 15:00:00', '2022-10-02 07:00:00', '2022-09-01 14:00:00', '2022-10-01 01:00:00'] })
已尝试的操作
- 排序并设置Datetime为索引:
df['Datetime'] = pd.to_datetime(df['Datetime']) df = df.sort_values(['ID_Type', 'ID', 'Datetime']) df = df.set_index('Datetime')
- 使用
shift函数时遇到问题:
# 设Datetime为索引时无效,不设索引则抛出NotImplementedError df['24HoursAgo'] = df['Datetime'].shift(-1, freq='24H')
- 未按ID分组的检测逻辑(存在缺陷):
grouped_df['SameValue24hoursApart'] = grouped_df['Type_A_Value'] == grouped_df['Type_A_Value'].shift(-1, freq='24H')
解决方案
步骤1:预处理数据
转换Datetime为datetime类型,按ID和时间排序,同时提取每个ID对应类型的数值到统一列:
# 转换时间类型 df['Datetime'] = pd.to_datetime(df['Datetime']) # 按ID和时间排序,保证分组内时间顺序正确 df = df.sort_values(['ID', 'Datetime']) # 提取对应类型的数值,生成统一Value列 df['Value'] = df.apply(lambda row: row[f'Type_{row["ID_Type"]}_Value'], axis=1)
步骤2:按ID分组检测24小时间隔重复值
通过分组后匹配每条记录的24小时前时间点,检查是否存在相同值:
def mark_24h_duplicates(group): # 计算每条记录的24小时前时间点 group['24h_ago'] = group['Datetime'] - pd.Timedelta(hours=24) # 构建分组内时间-值的映射字典 time_value_map = group.set_index('Datetime')['Value'].to_dict() # 标记当前记录是否存在24小时前的相同值 group['SameValue24hoursApart'] = group.apply( lambda row: time_value_map.get(row['24h_ago'], None) == row['Value'], axis=1 ) return group # 应用分组函数 df = df.groupby('ID', group_keys=False).apply(mark_24h_duplicates)
结果说明
SameValue24hoursApart列为布尔值,True表示该记录存在间隔24小时的相同值(同ID、同类型数值)- 无需将
Datetime设为索引,避免shift(freq)的使用限制 - 按ID分组确保检测逻辑仅在同一设备的记录中生效
内容的提问来源于stack exchange,提问作者coghlan
相关产品推荐
相关产品推荐

