如何在Pandas中按ID筛选Datetime列差值最小的符合条件行
解决方案
问题分析
你原来的代码存在两个核心问题:
- 将计算出的时间差秒数直接覆盖为布尔值(True/False),丢失了实际差值的大小,导致无法筛选每组内的最小差值行
- 分组维度错误,应该按
ID分组来获取每个ID的最小差值行,而非RT_Date和DateCreated
修正步骤与代码
- 保留实际时间差的秒数值,单独用新列存储布尔标记
- 筛选出时间差≤30秒的行
- 按
ID分组,提取每组中时间差最小的行 - 格式化生成
Nearest列
完整代码如下:
import pandas as pd df = pd.DataFrame({ 'RT_Date': ['2021-02-19 17:59:00', '2021-02-19 17:59:00', '2021-02-19 17:59:00', '2021-02-19 17:59:00'], 'ID': ['101', '101', '102', '102'], 'DateCreated': ['2021-02-19 17:58:38', '2021-02-19 17:58:31', '2021-02-19 17:58:38', '2021-02-19 17:58:41'] }) # 转换时间类型 df['RT_Date'] = pd.to_datetime(df['RT_Date']) df['DateCreated'] = pd.to_datetime(df['DateCreated']) # 计算时间差秒数,保留数值用于后续比较 df['Diff_Seconds'] = (df['RT_Date'] - df['DateCreated']).dt.total_seconds() # 生成布尔标记列,判断是否≤30秒 df['Diff'] = df['Diff_Seconds'] <= 30 # 筛选符合条件的行,按ID分组后取差值最小的行 result = df[df['Diff']].sort_values('Diff_Seconds').groupby('ID').first().reset_index() # 生成格式化的Nearest列 result['Nearest'] = result['Diff_Seconds'].apply(lambda x: f"{int(x)} seconds") # 调整列顺序,匹配预期输出 result = result[['RT_Date', 'ID', 'DateCreated', 'Diff', 'Nearest']] print(result)
代码说明
dt.total_seconds():直接用pandas的datetime属性计算秒数,比apply更高效- 筛选
df[df['Diff']]:只保留时间差≤30秒的行 sort_values('Diff_Seconds').groupby('ID').first():先按差值排序,分组后取每组第一行即为差值最小的行- 最后调整列顺序,生成符合预期的
Nearest格式化文本
执行后输出:
RT_Date ID DateCreated Diff Nearest 0 2021-02-19 17:59:00 101 2021-02-19 17:58:38 True 22 seconds 1 2021-02-19 17:59:00 102 2021-02-19 17:58:41 True 19 seconds
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

