如何在Pandas DataFrame中确保观测值间的最小时间间隔?
高效筛选Pandas时间序列:保留最小间隔的观测值
我有一个按日期列排序的Pandas DataFrame,需要确保观测值之间存在最小时间间隔(以10分钟为例:首个观测值在8:05,下一个需≥8:15,期间的观测值删除;第二个观测值若在8:17,则8:17-8:27间的观测值删除,以此类推)。
当前用逐行循环的脚本能实现需求,但几十万行的数据集上运行极慢,代码如下:
cur_time = df.iloc[0].Date for idx, row in df[1:].iterrows(): time_diff = (row.Date - cur_time).total_seconds() if time_diff > window*60: cur_time = row.Date else: trades_df.drop(idx, inplace=True)
请问有没有更高效的优化方法?将日期列设为索引后是否有现成函数可实现该功能?
补充:调研发现df.resample(window + 'M').first()功能类似,但数据集是稀疏数据(间隔从1秒到1个月不等),该方法不适用。
优化方案
核心问题分析
原来的代码性能差有两个关键原因:
iterrows()逐行生成Series对象,单循环开销极大;- 频繁调用
drop(idx, inplace=True)会不断重排DataFrame的列存储数据,导致性能急剧下降。
方法1:纯Numpy循环(比原方法快10-50倍)
直接操作日期的数值化timestamp,避免逐行Series的开销:
import pandas as pd import numpy as np # 确保日期列是datetime类型(如果还不是) df['Date'] = pd.to_datetime(df['Date']) window_minutes = 10 window_seconds = window_minutes * 60 # 初始化保留标记数组 keep = np.zeros(len(df), dtype=bool) keep[0] = True last_kept_ts = df['Date'].iloc[0].timestamp() for i in range(1, len(df)): current_ts = df['Date'].iloc[i].timestamp() if current_ts - last_kept_ts >= window_seconds: keep[i] = True last_kept_ts = current_ts # 一次性筛选结果 filtered_df = df[keep].reset_index(drop=True)
方法2:Numba编译加速(比原方法快50-200倍)
用Numba将循环编译为机器码,适合超大规模数据集:
import pandas as pd import numpy as np from numba import jit # 确保日期列是datetime类型 df['Date'] = pd.to_datetime(df['Date']) window_minutes = 10 window_seconds = window_minutes * 60 # 把日期转为int64类型的timestamp(Numba对数值类型处理更高效) dates_ts = df['Date'].astype(np.int64).values @jit(nopython=True) def filter_dates(dates, window): n = len(dates) keep = np.zeros(n, dtype=np.bool_) keep[0] = True last_kept = dates[0] for i in range(1, n): if dates[i] >= last_kept + window * 1_000_000_000: # Pandas的timestamp是纳秒级 keep[i] = True last_kept = dates[i] return keep # 生成保留标记并筛选 keep = filter_dates(dates_ts, window_seconds) filtered_df = df[keep].reset_index(drop=True)
关于日期列设为索引
将日期列设为DatetimeIndex本身没有现成函数直接实现该动态阈值筛选逻辑,但可以利用索引的数值化特性优化计算(比如直接用df.index.astype(np.int64)获取timestamp,比列访问略快),核心筛选逻辑还是需要用上述循环或编译方法。
内容的提问来源于stack exchange,提问作者Tommy
相关产品推荐
相关产品推荐

