如何在SortedKeyList中按ID筛选并获取最早时间戳的元素
解决方法
你的问题出在min函数的key里返回了None——当元素ID不符合时,key值为None,而datetime64类型和None无法进行小于比较,因此抛出TypeError。下面提供几个可行的解决思路:
方法一:先过滤再取最小
先筛选出目标ID的元素,再对这些元素取timestamp最小的。SortedKeyList是可迭代对象,可以用生成器表达式高效过滤:
target_id = "A" # 生成器过滤出ID匹配的元素 matching_points = (p for p in point_list if p.id == target_id) # 对过滤后的元素取timestamp最小的 try: earliest_point = min(matching_points, key=lambda x: x.timestamp) print(earliest_point.timestamp) except ValueError: print(f"未找到ID为{target_id}的元素")
方法二:利用有序性直接找第一个匹配元素
因为你的SortedKeyList是按timestamp升序排列的,第一个出现的目标ID元素就是时间最早的,所以遍历到第一个匹配项即可停止,无需遍历整个列表,效率更高:
target_id = "A" earliest_point = None for p in point_list: if p.id == target_id: earliest_point = p break # 找到第一个匹配项就退出循环 if earliest_point: print(earliest_point.timestamp) else: print(f"未找到ID为{target_id}的元素")
方法三:重构数据结构(适合频繁查询场景)
如果需要多次按ID查询最早元素,可以维护一个按ID分组的有序列表结构,每次添加元素时同步更新分组,查询时直接取对应分组的第一个元素(分组同样按timestamp排序):
import numpy as np import sortedcontainers class Point: def __init__(self, timestamp, id): self.timestamp = timestamp self.id = id # 封装管理类,维护主列表和按ID分组的有序列表 class PointStore: def __init__(self): self.main_list = sortedcontainers.SortedKeyList(key=lambda x: x.timestamp) self.id_groups = {} def add_point(self, point): self.main_list.add(point) # 初始化对应ID的有序列表 if point.id not in self.id_groups: self.id_groups[point.id] = sortedcontainers.SortedKeyList(key=lambda x: x.timestamp) self.id_groups[point.id].add(point) def get_earliest_by_id(self, target_id): group = self.id_groups.get(target_id) return group[0] if group else None # 使用示例 store = PointStore() store.add_point(Point(np.datetime64("2021-07-05T09:00:00"), "B")) store.add_point(Point(np.datetime64("2021-07-05T09:00:01"), "A")) store.add_point(Point(np.datetime64("2021-07-05T09:00:03"), "A")) store.add_point(Point(np.datetime64("2021-07-05T09:01:00"), "B")) earliest_a = store.get_earliest_by_id("A") print(earliest_a.timestamp) # 输出2021-07-05T09:00:01
该方法查询时间复杂度为O(1),适合频繁按ID查询的场景,代价是插入时多了维护分组的开销。
内容的提问来源于stack exchange,提问作者cicciodevoto
相关产品推荐
相关产品推荐

