2017-04-14 1 views
1

J'utilise DescriptiveStatistics pour suivre la moyenne mobile de certaines mesures. J'ai un thread qui soumet la valeur de métrique toutes les minutes, et je dépiste la moyenne mobile de 10 minutes de la métrique en utilisant la méthode setWindowSize(10) sur DescriptiveStatistics. Cela fonctionne très bien pour suivre une moyenne mobile unique, mais j'ai en fait besoin de suivre plusieurs moyennes mobiles, c'est-à-dire la moyenne de 1 minute, la moyenne de 5 minutes et la moyenne de 10 10 minutes.Suivre plusieurs moyennes mobiles avec Apache Commons Math DescriptiveStatistics

Actuellement, j'ai les options suivantes:

  1. ont 3 différentes instances avec 3 fenêtres statistique descriptive différentes. Cependant, cela signifie que nous stockons les mesures brutes plusieurs fois, ce qui n'est pas idéal.

  2. Have 1 instance de statistique descriptive et faire quelque chose comme ce qui suit lors de l'interrogation pour une moyenne mobile:

    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(); 
    

Cependant, l'option 2 signifie que je dois re-calculer un tas de moyennes tous les temps que je demande pour une moyenne mobile dont la fenêtre est plus petite que la taille de la fenêtre DescriptiveStats.

Y at-il un moyen de faire mieux? Je veux stocker 1 copie des données métriques et calculer continuellement N moyennes mobiles de celui-ci avec différents intervalles. Cela pourrait être dans le pays de Codahale Metrics ou Netflix Servo, mais je ne veux pas avoir à utiliser une bibliothèque de poids lourds juste pour cela.

Répondre

0

Vous pouvez utiliser la classe d'utilitaires StatUtils et gérer la baie lors de l'ajout de nouvelles valeurs. Une alternative est d'utiliser CircularFifoQueue de Apache Commons avec une taille de 10 et Apache Utils pour simplifier la conversion en tableau de valeurs primitives.

Vous pouvez trouver un exemple de StatUtils dans le User Guide, ce qui suit serait quelque chose de similaire à votre cas d'utilisation.

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);