如何高效筛选落在指定日期范围内的DataFrame时间戳行
高效筛选时间戳在任意区间内的DataFrame行
数据预处理
首先需要把字符串格式的时间转换为pandas的datetime类型,调整原始ISO格式中的分隔符:
import pandas as pd # 构造示例数据 df1 = pd.DataFrame({ 'date_start': ['2023-10-23T12-59-23-100Z', '2023-10-24T08-00-00-100Z'], 'date_end': ['2023-10-23T19-27-15-763Z', '2023-10-24T11-00-46-331Z'], 'state': ['state3', 'state3'] }) df2 = pd.DataFrame({ 'timestamp': ['2023-10-23T17-18-56-341Z', '2023-10-24T11-46-31-887Z'], 'value': [1500, 4671] }) # 解析ISO格式时间字符串 def parse_iso_time(s): # 替换分隔符:T后换空格,前两个-换:,最后一个-换.,去掉末尾Z formatted = s.replace('T', ' ').replace('-', ':', 2).replace('-', '.').rstrip('Z') return pd.to_datetime(formatted, format='%Y-%m-%d %H:%M:%S.%f') df1['date_start'] = df1['date_start'].apply(parse_iso_time) df1['date_end'] = df1['date_end'].apply(parse_iso_time) df2['timestamp'] = df2['timestamp'].apply(parse_iso_time)
方法1:使用IntervalIndex(简洁直观)
利用pandas的IntervalIndex创建时间区间集合,快速判断每个时间戳是否落在任意区间内:
# 创建包含所有时间区间的索引,closed='both'表示包含区间两端点 intervals = pd.IntervalIndex.from_arrays(df1['date_start'], df1['date_end'], closed='both') # 筛选符合条件的行 filtered_df2 = df2[df2['timestamp'].apply(lambda ts: intervals.contains(ts).any())]
方法2:Numpy广播(性能最优)
通过numpy的广播机制实现向量化比较,避免Python循环,处理大数据量时速度最快:
import numpy as np # 转换为numpy数组 timestamps = df2['timestamp'].to_numpy() starts = df1['date_start'].to_numpy() ends = df1['date_end'].to_numpy() # 广播比较:每个时间戳和所有区间对比,只要有一个区间符合条件就保留 mask = ((timestamps[:, np.newaxis] >= starts) & (timestamps[:, np.newaxis] <= ends)).any(axis=1) filtered_df2 = df2[mask]
方法3:交叉合并筛选(小数据量适用)
适合数据量较小的场景,逻辑简单易懂:
# 交叉合并两个DataFrame merged = df2.merge(df1, how='cross') # 筛选时间戳在区间内的行 matched = merged[(merged['timestamp'] >= merged['date_start']) & (merged['timestamp'] <= merged['date_end'])] # 去重并保留原始df2的列 filtered_df2 = matched[['timestamp', 'value']].drop_duplicates()
三种方法都能得到目标输出,其中Numpy广播法性能最优,IntervalIndex法代码最简洁,可根据数据规模选择合适的方案。
内容的提问来源于stack exchange,提问作者valeriova96
相关产品推荐
相关产品推荐

