使用Perl为每个唯一ID累积一个CSV列

时间:2013-11-08 01:58:54

标签: perl csv

我有一个如下所示的CSV文件:

1.0,25,some_value,01
1.0,25,some_value,01
1.0,10,some_value,02
1.0,10,some_value,02
1.0,3,some_value,03
1.0,3,some_value,03

我正在积累第二列的值 使用此Perl程序进入标量$sum

use strict;
use warnings;

my $sum = 0;
my $i = 0;
my @cols;

while (my $line = <STDIN>) {
  chomp $line;
  push @cols, [ split ",", $line ];
  $sum += $cols[$i][1];
  $i++;
}

print "$sum\n";

这将获得总和76,它是第二列中所有值的总和。

如果您回头看上面的CSV文件,最后一列代表一个ID。我真正需要的是获取最后一列第四列中每个ID的第二列的总和。 ID 01的第二列总和为50,ID 02为20,ID 03为6。

我不确定从何处开始实现,或者是否可以将其用于我的代码。

2 个答案:

答案 0 :(得分:2)

您所要做的就是使用哈希来存储每个唯一ID的总和:

use strict;
use warnings;

my %sum; # key: the unique id, value: the sum
while (my $line = <STDIN>) {
    chomp $line;
    my @cols = split /,/, $line;
    $sum{$cols[3]} += $cols[1];

}

for (sort { $a <=> $b } keys %sum) {
    print "$_: $sum{$_}\n";
} 

这将打印:

01: 50
02: 20
03: 6

答案 1 :(得分:2)

您的代码将整个输入放入数组@cols。当你需要的只是一列的总和,这是一个巨大的内存浪费。

您的程序可以编写

my $sum;
while (my $line = <STDIN>) {
  my @fields = split /,/, $line;
  $sum += $fields[1];
}

可以很容易地修改它以使用哈希对总和进行分类。此代码使用最后一个字段作为键来标识应该增加第二个字段值的哈希元素。

my %sums;
while (my $line = <DATA>) {
  chomp $line;
  my @fields = split /,/, $line;
  $sums{$fields[-1]} += $fields[1];
}

use Data::Dump;
dd \%sums;

<强>输出

{ "01" => 50, "02" => 20, "03" => 6 }