7

在 Boost.Accumulator 中,您可以将样本添加到累加器中,然后从中提取统计量。例如:

acc(1.)
acc(2.)
acc(3.)
cout << mean; // 2

该库有许多更复杂的统计量,例如skewnesskurtosisp_square_cumulative_distribution.

我想做的是这样的:

acc(1.)
acc(2.)
acc(3.)
std::cout << mean(acc); // 2
acc.pop() // withdraw the first value (1.)
std::cout << mean(acc); // 2.5

pop()将以 FIFO(先进先出)方式工作。我正在尝试做的是在滑动时间窗口内以在线(增量)方式计算我的数据的统计信息。

累加器必须在内部保留所有值。

我可以自己做,但我总是喜欢先检查现有库,并且可能有我不知道的算法可以在数据传入或传出时巧妙地计算数量。

4

3 回答 3

10

既然你提到了“滑动时间窗口”,一个选择是使用滚动平均值(还有滚动和和滚动计数),这是最后N个样本的平均值。根据您的需要,您可以创建具有不同窗口大小的单独累加器。

typedef accumulator_set<double,
                stats<tag::rolling_mean>
                > my_accumulator;

my_accumulator acc(tag::rolling_window::window_size = 3);
acc(1.);
acc(2.);
acc(3.);
std::cout << rolling_mean(acc);
// Reset accumulator and use different window size
acc = my_accumulator(tag::rolling_window::window_size = 2);
acc(2.);
acc(3.);
std::cout << rolling_mean(acc);

此外,如果您查看这些的实现,它们使用boost/circular_buffer.hpp.

于 2012-09-26T03:19:05.037 回答
2

您可能希望将数据存储在 astd::deque而不是向量中,因此您的插入和删除都可以具有恒定的复杂性。如果您使用向量,则不可避免地会是线性的。

除此之外,将算法应用于集合是一件非常简单的事情。然而,奇怪的是,我不知道已经编写和测试过的此类算法的集合,尽管看起来有一组相当明显的算法可用。

对于它的价值,构建一个适配器以将数据从集合馈送到累加器以计算您可以计算的统计数据是相当简单的。在少数情况下,累加器可能需要做一些额外的工作来逐步计算结果,但我猜想失去足够的效率来关心是非常罕见的。

于 2012-09-26T02:48:54.020 回答
1

您可能需要将所有样本保存在一个向量中,然后从向量中为每次计算累积它们。像这样的东西:https ://stackoverflow.com/a/7616783/219136

于 2012-09-26T01:36:05.197 回答