Streaming Average

Just because I keep forgetting it and having to find out all the math manually again!

my $avg = 0;
my $cnt = 0;
for my $row (@rows) {
    if ($cnt) {
       $avg += (($row->{value} - $avg)/($cnt+$row->{cnt}))*$row->{cnt};
       $cnt += $row->{cnt};
    } else {
       $cnt = $row->{cnt};
       $avg = $row->{value};
    }
}

The two main reasons to use something like this is if your total is too big and you don’t care about standard deviations – I’m pretty sure we can come up with a streaming formula for the standard deviation as well.

Also, if you @rows is some type of stream in which you have a way to get the next value and you want to know the average so far at any given point, this is the way to do it.


Source: theMage