如何高效检查嵌套Timestamp列表中是否存在3个时间戳在指定范围?
问题描述
我有一个嵌套列表,每个子列表是长度4到250的Timestamp序列。我已经知道怎么检查两个Timestamp是否在指定时间范围内,但不知道怎么检查是否存在3个Timestamp处于该范围?
附上我写的代码,这段代码冗余低效,还存在索引越界问题,求更优实现方案:
master = [Timestamp('2014-03-11 00:00:00'), Timestamp('2014-03-12 00:00:00'), Timestamp('2014-03-13 00:00:00'), Timestamp('2014-05-07 00:00:00'), Timestamp('2014-05-11 00:00:00'), Timestamp('2014-05-28 00:00:00'), Timestamp('2014-05-29 00:00:00')] [Timestamp('2014-03-09 00:00:00'), Timestamp('2014-04-02 00:00:00'), Timestamp('2014-04-15 00:00:00'), Timestamp('2014-04-23 00:00:00'), Timestamp('2014-05-01 00:00:00')] [Timestamp('2013-08-09 00:00:00'), Timestamp('2013-08-13 00:00:00'), Timestamp('2013-09-05 00:00:00'), Timestamp('2013-09-11 00:00:00'), Timestamp('2013-09-24 00:00:00')] [Timestamp('2014-04-02 00:00:00'), Timestamp('2014-04-11 00:00:00'), Timestamp('2014-04-30 00:00:00'), Timestamp('2014-05-05 00:00:00'), Timestamp('2014-05-15 00:00:00'), Timestamp('2014-05-21 00:00:00')] [Timestamp('2012-11-16 00:00:00'), Timestamp('2012-11-28 00:00:00'), Timestamp('2012-12-09 00:00:00'), Timestamp('2012-12-10 00:00:00'), Timestamp('2012-12-22 00:00:00'), Timestamp('2013-01-14 00:00:00'), Timestamp('2013-01-31 00:00:00')] [Timestamp('2012-11-23 00:00:00'), Timestamp('2013-01-01 00:00:00'), Timestamp('2013-01-02 00:00:00'), Timestamp('2013-01-07 00:00:00'), Timestamp('2013-01-17 00:00:00')] final_result = [] for stamp in master: sub_list = [] stamp = stamp.sort(reverse = True) x1 = stamp[0] - stamp[1] x2 = stamp[1] - stamp[2] if x1+x2 <=7: sub_list.append(1) continue else: sub_list.append(0) if 1 in sub_list: final_result.append(1) else: final_result.append(0)
优化方案
核心思路
要检查是否存在3个Timestamp在指定时间范围(比如7天)内,最高效的方式是先对每个子列表的Timestamp排序,然后用滑动窗口检查连续3个Timestamp的首尾时间差是否≤指定阈值。排序后只需检查连续元素即可——因为如果存在非连续的三个元素满足条件,其中必然有连续的三个也满足(排序后时间呈递增/递减顺序)。
代码实现
import pandas as pd # 整理嵌套列表(原代码中仅第一个列表存入master,其余未正确赋值) timestamp_lists = [ [pd.Timestamp('2014-03-11 00:00:00'), pd.Timestamp('2014-03-12 00:00:00'), pd.Timestamp('2014-03-13 00:00:00'), pd.Timestamp('2014-05-07 00:00:00'), pd.Timestamp('2014-05-11 00:00:00'), pd.Timestamp('2014-05-28 00:00:00'), pd.Timestamp('2014-05-29 00:00:00')], [pd.Timestamp('2014-03-09 00:00:00'), pd.Timestamp('2014-04-02 00:00:00'), pd.Timestamp('2014-04-15 00:00:00'), pd.Timestamp('2014-04-23 00:00:00'), pd.Timestamp('2014-05-01 00:00:00')], [pd.Timestamp('2013-08-09 00:00:00'), pd.Timestamp('2013-08-13 00:00:00'), pd.Timestamp('2013-09-05 00:00:00'), pd.Timestamp('2013-09-11 00:00:00'), pd.Timestamp('2013-09-24 00:00:00')], [pd.Timestamp('2014-04-02 00:00:00'), pd.Timestamp('2014-04-11 00:00:00'), pd.Timestamp('2014-04-30 00:00:00'), pd.Timestamp('2014-05-05 00:00:00'), pd.Timestamp('2014-05-15 00:00:00'), pd.Timestamp('2014-05-21 00:00:00')], [pd.Timestamp('2012-11-16 00:00:00'), pd.Timestamp('2012-11-28 00:00:00'), pd.Timestamp('2012-12-09 00:00:00'), pd.Timestamp('2012-12-10 00:00:00'), pd.Timestamp('2012-12-22 00:00:00'), pd.Timestamp('2013-01-14 00:00:00'), pd.Timestamp('2013-01-31 00:00:00')], [pd.Timestamp('2012-11-23 00:00:00'), pd.Timestamp('2013-01-01 00:00:00'), pd.Timestamp('2013-01-02 00:00:00'), pd.Timestamp('2013-01-07 00:00:00'), pd.Timestamp('2013-01-17 00:00:00')] ] def has_three_within_range(timestamps, max_days=7): # 排序Timestamp序列,默认升序 sorted_ts = sorted(timestamps) # 遍历连续三个元素的窗口,避免索引越界 for i in range(len(sorted_ts) - 2): # 计算第一个和第三个Timestamp的时间差 delta = sorted_ts[i+2] - sorted_ts[i] if delta.days <= max_days: return 1 return 0 # 生成最终结果 final_result = [has_three_within_range(ts_list) for ts_list in timestamp_lists] print(final_result)
关键优化点
- 修复原代码错误:原代码中
sort()是原地修改方法,返回None,导致后续索引操作报错;同时修正了子列表未正确存入嵌套列表的问题。 - 降低时间复杂度:排序时间为O(n log n),遍历检查为O(n),远低于暴力枚举所有三元组的O(n³),适合子列表长度较大的场景。
- 避免索引越界:遍历范围控制在
len(sorted_ts)-2,确保i+2不会超出列表边界,兼容4到250长度的所有子列表。
内容的提问来源于stack exchange,提问作者Fernando Araiza
相关产品推荐
相关产品推荐

