我正在使用 DescriptiveStatistics跟踪某些指标的移动平均值。我有一个线程每分钟提交一次指标值,我使用 DescriptiveStatistics 上的 setWindowSize(10)
方法跟踪指标的 10 分钟移动平均值。
这适用于跟踪单个移动平均线,但实际上我需要跟踪多个移动平均线,即 1 分钟平均线、5 分钟平均线和 10 分钟平均线。
目前我有以下选择:
有 3 个不同的 DescriptiveStatistics 实例和 3 个不同的窗口。然而,这意味着我们多次存储原始指标,这并不理想。
有 1 个 DescriptiveStatistics 实例,并在查询移动平均线时执行类似以下操作:
int minutes = <set from parameter>; DescriptiveStatistics stats = <class variable>; if (minutes == stats.getN()) return stats.getMean(); SummaryStatistics subsetStats = new SummaryStatistics(); for (int i = 0; i < minutes; i++) { subsetStats.addValue(stats.getElement((int)stats.getN() - i - 1)); } return subsetStats.getMean();
但是,选项 2 意味着每次查询窗口小于 DescriptiveStats 窗口大小的移动平均线时,我都必须重新计算一堆平均值。
有没有更好的方法?我想存储 1 个指标数据副本,并以不同的时间间隔连续计算它的 N 个移动平均值。这可能会进入 Codahale Metrics 或 Netflix Servo 领域,但我不想为此使用重量级库。
最佳答案
您可以使用 StatUtils
实用程序类并在添加新值时管理数组。一种替代方法是使用 Apache Commons 的 CircularFifoQueue
大小为 10 和 Apache Utils 以简化原始值数组的转换。
您可以在 User Guide 中找到 StatUtils
的示例,以下将与您的用例类似。
CircularFifoQueue<Double> queue = new CircularFifoQueue<>(10);
// Add your values
double[] values = ArrayUtils.toPrimitive(queue.toArray(new Double[0]))
mean1 = StatUtils.mean(values, 0, 1);
mean5 = StatUtils.mean(values, 0, 5);
mean10 = StatUtils.mean(values, 0, 10);
关于java - 使用 Apache Commons Math DescriptiveStatistics 跟踪多个移动平均线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43420275/