http://www.perlmonks.org?node_id=971998


in reply to calculate average in sliding windows

Maybe this will help?

#! perl -slw use strict; use Data::Dump qw[ pp ]; use List::Util qw[ sum ]; use constant WINDOW => 10; my @data = map int( rand 10 ), 1 .. 30; my @mAves; my @slide; for my $dp ( @data ) { push @slide, $dp; shift @slide if @slide > WINDOW; push @mAves, sum( @slide ) / WINDOW if @slide == WINDOW; } print join ' ', @data; print join ' ', @mAves; __END__ C:\test>junk 3 8 8 2 5 5 0 3 8 3 2 3 2 3 5 4 8 7 5 4 6 3 1 6 3 6 0 7 3 3 4.5 4.4 3.9 3.3 3.4 3.4 3.3 4.1 4.5 4.2 4.3 4.7 + 4.7 4.6 4.9 4.7 4.9 4.1 4.1 3.9 3.8

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

The start of some sanity?

Replies are listed 'Best First'.
Re^2: calculate average in sliding windows
by Eliya (Vicar) on May 23, 2012 at 11:47 UTC

    A less computationally intensive variant would be to directly maintain a $sum, to which you add/subtract individual values (instead of push/shift on an array, from which you then recompute the sum every time):

    #!/usr/bin/perl -lw use strict; use constant WINDOW => 10; #my @data = map int( rand 10 ), 1 .. 30; my @data = qw(3 8 8 2 5 5 0 3 8 3 2 3 2 3 5 4 8 7 5 4 6 3 1 6 3 6 0 7 +3 3); my @mAves; my $sum = 0; for my $i (0..$#data) { $sum += $data[$i]; $sum -= $data[$i-WINDOW()] if $i >= WINDOW; push @mAves, $sum / WINDOW if $i >= WINDOW-1; } print join ' ', @data; print join ' ', @mAves; __END__ 3 8 8 2 5 5 0 3 8 3 2 3 2 3 5 4 8 7 5 4 6 3 1 6 3 6 0 7 3 3 4.5 4.4 3.9 3.3 3.4 3.4 3.3 4.1 4.5 4.2 4.3 4.7 + 4.7 4.6 4.9 4.7 4.9 4.1 4.1 3.9 3.8