如何用Pandas筛选时间间隔不小于5秒的DataFrame数据
基于时间间隔筛选排序后的Pandas DataFrame
需求描述
现有一个按datetime列ts排序的Pandas DataFrame,需要生成新的DataFrame,规则如下:
- 新DataFrame的第一行与原DataFrame的第一行完全相同
- 仅当原DataFrame中的行与新DataFrame最后一行的时间间隔至少为5秒时,才将该行加入新DataFrame
- 要求使用Pandas原生/高效向量化方法(避免纯Python循环,适配大数据量),且支持毫秒级时间粒度
示例数据
原始DataFrame
import pandas as pd df = pd.DataFrame({'ts': [ '2022-01-01 00:00:00', '2022-01-01 00:00:03', '2022-01-01 00:00:04', '2022-01-01 00:00:06', '2022-01-01 00:00:08', '2022-01-01 00:00:10', '2022-01-01 00:00:12', '2022-01-01 00:00:15', '2022-01-01 00:00:17', '2022-01-01 00:00:20' ]})
期望结果
result = pd.DataFrame({'ts': [ '2022-01-01 00:00:00', '2022-01-01 00:00:06', '2022-01-01 00:00:12', '2022-01-01 00:00:17' ]})
高效解决方案
步骤说明
- 将
ts列转换为Pandas datetime类型(天然支持毫秒级精度) - 利用numpy的累积操作实现高效的选中时间跟踪,避免纯Python循环的性能瓶颈
- 通过比较原时间列与累积生成的选中时间序列,筛选出符合条件的行
完整代码
import pandas as pd import numpy as np # 1. 转换ts列为datetime类型,自动识别毫秒格式 df['ts'] = pd.to_datetime(df['ts']) # 2. 定义累积判断函数:更新选中的时间点 def update_selected(last_selected_ts, current_ts): if current_ts - last_selected_ts >= pd.Timedelta(seconds=5): return current_ts return last_selected_ts # 3. 用numpy累积计算每个位置的最后选中时间 ts_array = df['ts'].to_numpy() last_selected_array = np.frompyfunc(update_selected, 2, 1).accumulate(ts_array, dtype=object) # 4. 筛选符合条件的行 last_selected = pd.Series(last_selected_array, index=df.index) result = df[df['ts'] == last_selected].reset_index(drop=True) # 输出结果 print(result)
代码解释
pd.to_datetime(df['ts']):将字符串时间转为datetime64[ns]类型,可直接处理包含毫秒的时间字符串(如'2022-01-01 00:00:00.500')np.frompyfunc(...)结合accumulate:利用numpy的底层循环实现高效的逐行判断,性能远优于纯Python循环,适配十万级以上数据量- 最终通过比较原时间列与累积生成的选中时间序列,精准筛选出所有符合间隔要求的行
毫秒级场景验证
如果输入包含毫秒的时间数据:
df_ms = pd.DataFrame({'ts': [ '2022-01-01 00:00:00.000', '2022-01-01 00:00:03.500', '2022-01-01 00:00:05.100', # 与第一行间隔5.1秒,符合条件 '2022-01-01 00:00:09.900', '2022-01-01 00:00:10.200' # 与上一个选中时间间隔5.1秒,符合条件 ]})
执行代码后会得到正确结果:
ts 0 2022-01-01 00:00:00.000 1 2022-01-01 00:00:05.100 2 2022-01-01 00:00:10.200
内容的提问来源于stack exchange,提问作者SBF
相关产品推荐
相关产品推荐

