python - 在大小 > n 的移动窗口中跟踪前 n 个值?
问题描述
假设我们有一个每分钟输入一次的数据流,并且我们希望在前 10 分钟内跟踪前 5 个值。直觉上应该有一些队列解决方案,但我正在努力寻找一种优雅的方式,因为一个元素可以出于两种不同的原因弹出(它看起来在 11 分钟前或 <10 分钟前,但 5 个更高的值有从那以后就被看到了)
任何建议,将不胜感激!
解决方案
不要在这里忽略一个简单的事情——你可能会惊讶于它的效果。您有两个订单,因此请按排序顺序维护两个序列,按bytime
时间排序和byvalue
按价值排序。在每个中存储 2 元组(value, timestamp)
对。当然,您需要使它们保持同步。
由于byvalue
始终按值排序,因此您可以随时查看 top n
、 bottom n
、 middlen
或任何其他类型的顺序统计信息。
假设您的时间戳(无论对您意味着什么)只会随着时间的推移而增加,那么按时间“排序”是微不足道的:使用 acollections.deque
并在一端(例如右侧)推送新记录并从另一端丢弃。对 .使用普通列表byvalue
。要使旧记录过期,则:
oldest_to_retain = whatever form of timestamp you use
while bytime and bytime[0][1] < oldest_to_retain:
t = bytime.popleft() # discard expired record
# and remove it from the other seq too
i = bisect.bisect_left(byvalue, t)
assert byvalue[i] == t
del byvalue[i]
要插入传入值,
t = (the_new_value, current_timestamp)
assert not bytime or bytime[-1][1] <= current_timestamp
bytime.append(t)
bisect.insort(byvalue, t)
现在有了一些经验,人们对这个想法犹豫不决,因为这些陈述具有O()
线性行为len(byvalue)
:
del byvalue[i]
bisect.insort(byvalue, t)
(而其他语句具有O(1)
或O(log(N))
行为。)
有了更多的经验,他们就克服了 ;-) 这些以“C 速度”发生,除非byvalue
增长到数百个元素,否则它通常比花哨的树结构更快 - 并且更节省空间 - 即使它们被编码为优化C。
如果确实变大了,那么从广泛使用的packagebyvalue
切换byvalue
到使用 a是一个简单的改变。那么没有比 about 更糟糕的陈述了。您的代码部分仍然简单、灵活且易于推理。SortedList
sortedcontainers
O(log(N))
推荐阅读
- excel - 添加超链接 VBA
- css - 网格布局损坏且无响应
- python - 在数据框中创建行的子集和对应的列
- javascript - reactjs: execute a script only after render is complete after a certain part of state is changed
- reactjs - 在 React-Admin 上更改菜单背景颜色
- recursion - 从两个不同类型的两个列表创建一个元组
- haskell - haskell 检查字符串长度 - 非详尽模式异常
- javascript - 如果存在锚点,则自动打开弹出窗口
- c# - 超出数组c#的范围
- arrays - 按另一个数组中的元素对结构数组进行排序