Algorithm 获取数据流的平均值p95和p99
我有输入数据,我想计算该数据的平均值,第95和99个百分位-我最感兴趣的是最后1000个值。在任何时候,我都想查询这个对象以获得三个值中的任何一个(这可以在任何时候发生,而不仅仅是当mod 1000看到的数字为0时)。有没有办法在不保留最后1000个样本的情况下获得这三个值 这并不一定是完美的,所以我们可以使用一些技巧来获得一个好的估计。此外,速度是另一个问题。谢谢Algorithm 获取数据流的平均值p95和p99,algorithm,average,precision,moving-average,Algorithm,Average,Precision,Moving Average,我有输入数据,我想计算该数据的平均值,第95和99个百分位-我最感兴趣的是最后1000个值。在任何时候,我都想查询这个对象以获得三个值中的任何一个(这可以在任何时候发生,而不仅仅是当mod 1000看到的数字为0时)。有没有办法在不保留最后1000个样本的情况下获得这三个值 这并不一定是完美的,所以我们可以使用一些技巧来获得一个好的估计。此外,速度是另一个问题。谢谢 (我将在C++中做这件事,但我不认为这有什么关系)至少,你需要保持最近1000个元素的队列。 要保持运行平均值,请保持最近1000
(我将在C++中做这件事,但我不认为这有什么关系)
至少,你需要保持最近1000个元素的队列。 要保持运行平均值,请保持最近1000个元素的运行总数;向队列中添加新元素时,将其值添加到总数中,并减去刚从队列中删除的最旧元素的值。返回总数除以1000的结果 要保持运行的第n个百分位,请保持两个堆并保持堆中元素的计数;“较低”堆具有较低的N%的值,“较高”堆具有较高的(1-N)%(例如,较低的第95百分位堆将具有950个元素,而较高的第5百分位堆将具有50个元素)。在任何时候,您都可以从上层堆返回最低的元素,这就是您的百分比。从最近值队列中删除元素时,也要从堆中删除该值。如果这使得堆不平衡(例如,较低的堆有951个元素,而较高的堆有49个元素),则移动元素以平衡它们(例如,从较低的堆中移除顶部元素并将其添加到较高的堆中) 因为您想要两个百分位,所以使用三个堆-较低的堆包含较低的950个元素,中间的堆包含接下来的40个元素,而较高的堆包含最高的10个元素。返回中间堆的最低元素(第95百分位),返回上层堆的最低元素(第99百分位) 添加和删除堆元素的代价是O(lg(n)),这就是向队列和三个堆添加新元素的代价:从堆中删除最旧的队列元素(O(lg(n)),将新的队列元素添加到适当的堆中(O(lg(n)),并在需要时平衡堆(同样,O(lg(n))。将新元素添加到其最高元素大于堆元素的最低堆,即if (newElement < lowestHeap.maxElement) {
lowestHeap.add(newElement)
} else if (newElement < middleHeap.maxElement) {
middleHeap.add(newElement)
} else {
highestHeap.add(newElement)
}
if(newElement
确保您的堆允许重复元素首先让我们假设您能够存储1000个数字(假设k乘以1000,其中k是一个常数) 保持3堆:
我认为您可以保存1000个条目的数组,而不会带来太多麻烦或内存损失。问题是数据的顺序(我认为,如果您想要获得百分位数,您需要对其进行排序)是的,排序是最麻烦的部分。如果你不将数据保存在数组中,我认为没有办法计算任何百分位数,因此,算法(我认为应该是这样的)是:1.存储数据;2.排序数据(使用你最喜欢的方法);3.在所需位置获取值(
array[n]
其中n=round(array.length*p)
和0