For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > February 2007 > Simple averaging.









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Simple averaging.
Rich Bradshaw

2007-02-19, 7:58 am

Hi,

I have some data in the form:

1 1.4
1 1.5
1 1.2
1 5.7

2 4.6
2 4.9
2 8.9
2 3.4

etc

I would like to produce a new file that just has 1 instance of the
number in the first column and an average for the values associated
with it, so in this case I would like:

1 2.45
2 5.45

etc.

I am sure this is easy to do, but am confusing myself trying to write
a Perl script - does anyone care to show me how it is done?

Thanks!

Manish

2007-02-19, 6:58 pm

On Feb 19, 7:37 am, "Rich Bradshaw" <Rich.Brads...@gmail.com> wrote:
> Hi,
>
> I have some data in the form:
>
> 1 1.4
> 1 1.5
> 1 1.2
> 1 5.7
>
> 2 4.6
> 2 4.9
> 2 8.9
> 2 3.4
>
> etc
>
> I would like to produce a new file that just has 1 instance of the
> number in the first column and an average for the values associated
> with it, so in this case I would like:
>
> 1 2.45
> 2 5.45
>
> etc.
>
> I am sure this is easy to do, but am confusing myself trying to write
> a Perl script - does anyone care to show me how it is done?
>
> Thanks!


Please post what you have tried? I have no idea how your data is
stored?
Assuming you can retrieve the columns into couple of arrays,
I suggest doing somthing like this.

use warnings;
use strict;

my @column1 = qw/1.4 1.5 1.2 5.7 /;
my @column2 = qw/4.6 4.9 8.9 3.4/;
my $avg1 = 0;
my $sum = 0;
my $avg2 = 0;

foreach (@column1) { my $sum = $sum + $_;}
$avg1 = $sum/($#column1+1);

foreach (@column2) { my $sum = $sum + $_;}
$avg2 = $sum/($#column2+1);

#now open a new file xyz
open(NF, ">xyx") or die "couldln't open file xyz\n";

printn NF "1 $avg1\n";
printn NF "2 $avg2\n";

close NF;

Manish

2007-02-19, 6:58 pm

On Feb 19, 9:51 am, "Manish" <mar...@gmail.com> wrote:
> On Feb 19, 7:37 am, "Rich Bradshaw" <Rich.Brads...@gmail.com> wrote:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> Please post what you have tried? I have no idea how your data is
> stored?
> Assuming you can retrieve the columns into couple of arrays,
> I suggest doing somthing like this.
>
> use warnings;
> use strict;
>
> my @column1 = qw/1.4 1.5 1.2 5.7 /;
> my @column2 = qw/4.6 4.9 8.9 3.4/;
> my $avg1 = 0;
> my $sum = 0;
> my $avg2 = 0;
>
> foreach (@column1) { my $sum = $sum + $_;}


remove my before $sum;

> $avg1 = $sum/($#column1+1);
>
> foreach (@column2) { my $sum = $sum + $_;}


remove my before $sum;

> $avg2 = $sum/($#column2+1);
>
> #now open a new file xyz
> open(NF, ">xyx") or die "couldln't open file xyz\n";
>
> printn NF "1 $avg1\n";
> printn NF "2 $avg2\n";
>
> close NF;- Hide quoted text -
>
> - Show quoted text -


markrat@gmail.com

2007-02-19, 6:58 pm

On Feb 19, 7:37 am, "Rich Bradshaw" <Rich.Brads...@gmail.com> wrote:
> Hi,
>
> I have some data in the form:
>
> 1 1.4
> 1 1.5
> 1 1.2
> 1 5.7
>
> 2 4.6
> 2 4.9
> 2 8.9
> 2 3.4
>
> etc
>
> I would like to produce a new file that just has 1 instance of the
> number in the first column and an average for the values associated
> with it, so in this case I would like:
>
> 1 2.45
> 2 5.45
>
> etc.
>
> I am sure this is easy to do, but am confusing myself trying to write
> a Perl script - does anyone care to show me how it is done?
>
> Thanks!


#!/usr/bin/perl

use strict;
use warnings;

my %hash;
while ( <DATA> ) {
my ($col1, $col2) = split /\s+/;
$hash{$col1}->{total} += $col2;
$hash{$col1}->{count}++;
}

my $file = 'file.txt';
open my $fh, '>', $file or die "Cannot open $file: $!\n";
for ( keys %hash ) {
my $average = $hash{$_}->{total}/$hash{$_}->{count};
printf $fh "%d %.2f\n", $_, $average;
}
close $fh or die "Cannot close $file: $!\n";

__DATA__
1 1.4
1 1.5
1 1.2
1 5.7
2 4.6
2 4.9
2 8.9
2 3.4

Rich Bradshaw

2007-02-19, 6:58 pm

Thanks, that works well - I couldn't work out how to import each
column into a separate column in an array - split seems to work pretty
well!

I (somehow!) manged to modify the code to allow a filename to be
specified for input and export, I will post this here in case any else
may find it helpful.

#!/usr/bin/perl

use strict;
use warnings;

my %hash;
while ( <> ) {
my ($col1, $col2) = split /\s+/;
$hash{$col1}->{total} += $col2;
$hash{$col1}->{count}++;
}

for ( keys %hash ) {
my $average = $hash{$_}->{total}/$hash{$_}->{count};
printf "%f %.2f\n", $_, $average;
}

Call as:

../average.pl < inputfile.dat > exportfile.dat

Thanks for your help!

Rich Bradshaw

2007-02-19, 6:58 pm

On Feb 19, 2:54 pm, "Manish" <mar...@gmail.com> wrote:[color=darkred]
> On Feb 19, 9:51 am, "Manish" <mar...@gmail.com> wrote:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> remove my before $sum;
>
>
>
> remove my before $sum;
>
>
>
>
>

Thanks for your help, but the script below seems easier for me to
convert to enable me to input a existing file.

Thanks though!

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com