使用Apache Commons Math DescriptiveStatistics跟踪多个移动平均线

时间:2017-04-14 22:58:47

标签: java statistics apache-commons metrics usage-statistics

我正在使用DescriptiveStatistics来跟踪某些指标的移动平均值。我有一个每分钟提交度量值的线程,我使用DescriptiveStatistics上的setWindowSize(10)方法跟踪度量标准的10分钟移动平均值。

这适用于跟踪单个移动平均线,但我实际上需要跟踪多个移动平均线,即1分钟平均值,5分钟平均值和10分钟平均值。

目前我有以下选择:

  1. 拥有3个不同的DescriptiveStatistics实例和3个不同的窗口。但是,这意味着我们会多次存储原始指标,这是不理想的。

  2. 拥有一个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();
    
  3. 但是,选项2意味着每次查询窗口小于DescriptiveStats窗口大小的移动平均值时,我都必须重新计算一堆平均值。

    有没有办法更好地做到这一点?我希望存储1个度量数据副本,并以不同的间隔连续计算它的N个移动平均值。这可能会进入Codahale Metrics或Netflix Servo的土地,但我不想仅仅为了这个而使用重量级的库。

1 个答案:

答案 0 :(得分:1)

您可以使用StatUtils实用程序类并在添加新值时管理数组。另一种方法是使用大小为10的CircularFifoQueue StatUtils和Apache Utils来简化向原始值数组的转换。

您可以在Apache Commons中找到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); 的示例,以下内容与您的用例类似。

'idp' => array (
    'entityId' => 'https://app.onelogin.com/saml/metadata/123456',
    'singleSignOnService' => array (
        'url' => 'https://app.onelogin.com/trust/saml2/http-post/sso/123456',
    ),
    'singleLogoutService' => array (
        'url' => 'https://app.onelogin.com/trust/saml2/http-redirect/slo/123456',
    ),
    'x509cert' => 'XXXXxXXX1xXxXXXxXXXXXXxXXxxXx...',
)