如何在Pandas DataFrame中按时间间隔阈值筛选保留数据行?
筛选Pandas DataFrame中满足时间间隔阈值的行
我有一个存储日志数据的Pandas DataFrame,采样周期远短于实际需求,需要筛选出当前行与前一行时间差≥60秒的记录,删除不符合条件的行。原本打算用iterrows()实现,但Pandas文档指出不应在迭代时修改迭代对象,作为Python和Pandas新手,不确定该用什么正确工具完成需求。
示例输入DataFrame
DateTime Value 3/1/2023 0:00:00 0.12 3/1/2023 0:00:03 0.12 3/1/2023 0:00:13 0.12 3/1/2023 0:00:23 0.12 3/1/2023 0:00:33 0.12 3/1/2023 0:00:43 0.12 3/1/2023 0:00:53 0.12 3/1/2023 0:01:03 0.12 3/1/2023 0:01:13 0.12 3/1/2023 0:01:23 0.12 3/1/2023 0:01:33 0.12 3/1/2023 0:01:43 0.13 3/1/2023 0:01:53 0.13 3/1/2023 0:02:03 0.13 3/1/2023 0:02:13 0.12
期望输出
DateTime Value 3/1/2023 0:00:00 0.12 3/1/2023 0:01:03 0.12 3/1/2023 0:02:03 0.13 3/1/2023 0:02:13 0.12
解决方案:使用Pandas矢量化操作实现
不用iterrows()这种低效的迭代方式,Pandas的矢量化方法更高效且符合最佳实践,步骤如下:
确保
DateTime列为时间类型
首先要把字符串格式的时间列转换成Pandas的datetime类型,否则无法计算时间差:df['DateTime'] = pd.to_datetime(df['DateTime'])计算相邻行的时间差
使用diff()方法计算当前行与前一行的时间间隔,结果为Timedelta类型:time_diff = df['DateTime'].diff()筛选符合条件的行
我们需要保留第一行(因为它没有前一行),以及时间差≥60秒的行。用布尔索引实现:# 第一行设为True,其余行判断时间差是否≥60秒 mask = time_diff >= pd.Timedelta(seconds=60) mask.iloc[0] = True # 保留第一行 filtered_df = df[mask]完整代码示例
import pandas as pd # 构造示例数据 data = { 'DateTime': [ '3/1/2023 0:00:00', '3/1/2023 0:00:03', '3/1/2023 0:00:13', '3/1/2023 0:00:23', '3/1/2023 0:00:33', '3/1/2023 0:00:43', '3/1/2023 0:00:53', '3/1/2023 0:01:03', '3/1/2023 0:01:13', '3/1/2023 0:01:23', '3/1/2023 0:01:33', '3/1/2023 0:01:43', '3/1/2023 0:01:53', '3/1/2023 0:02:03', '3/1/2023 0:02:13' ], 'Value': [0.12]*7 + [0.12]*4 + [0.13]*3 + [0.12] } df = pd.DataFrame(data) # 转换时间列类型 df['DateTime'] = pd.to_datetime(df['DateTime']) # 计算时间差并生成筛选掩码 time_diff = df['DateTime'].diff() mask = time_diff >= pd.Timedelta(seconds=60) mask.iloc[0] = True # 筛选结果 filtered_df = df[mask] print(filtered_df)
运行后得到的结果就和期望输出一致。
为什么不用iterrows()?
iterrows()是逐行迭代,效率极低,尤其是处理大数据量时。而且迭代过程中修改原DataFrame容易引发不可预测的问题,Pandas官方推荐用矢量化操作(比如diff()、布尔索引)来处理这类批量数据筛选,速度快且代码更简洁。
内容的提问来源于stack exchange,提问作者jeffroboto
相关产品推荐
相关产品推荐

