Perl считает сумму одного столбца, агрегирующего другой - PullRequest
2 голосов
/ 28 декабря 2010

У меня в наборе данных будет много столбцов. Что мне нужно сделать, это суммировать совокупность одного столбца в терминах другого. Как пример,

ID       Volume
A          20
D          60
B          10
A          50
K          30 
B          100
D          80 

Итак, я хочу получить агрегированную сумму всех различных идентификаторов (A, B, C ...) по объемам и отсортировать по этой сумме

Результат будет выглядеть как

D           140
B           110
A           70
K           30

как бы я сделал это в Perl?

Ответы [ 3 ]

3 голосов
/ 28 декабря 2010
  #!/usr/bin/perl

  use strict;
  use warnings;

  my %ids_and_sums;

  while (<>) {
     # The regex will only consider one single uppercase letter as
     # an ID; in case your IDs may look different, you could prepend
     # your 'ID  Volume' line with a character which will never be part
     # of an ID, and modify below regex to meet your needs
     my ($id, $volume) = m/^([A-Z])\s+(\d+)/;

     if ($id and $volume) {
        $ids_and_sums{$id} += $volume;
     }
  }

  foreach my $key (sort {$ids_and_sums{$b} <=> $ids_and_sums{$a}} keys %ids_and_sums) {
     print "$key: $ids_and_sums{$key}\n";
  }

Это печатает:

D: 140
B: 110
A: 70
K: 30

РЕДАКТИРОВАТЬ: Я изменил код так, чтобы сортировка была в порядке убывания сумм.

2 голосов
/ 28 декабря 2010

Вы можете сделать это как:

perl -lnae '$H{$F[0]} += $F[1];END { print $_." ".$H{$_} for(keys %H) }'

передача всего, кроме первой строки вашего входного файла, в качестве стандартного ввода.

Ideone Link

Вы можете заставить Perl отбрасывать строку заголовка как:

perl -lnae 'BEGIN{$i=1;}if($i){$i=0;next;}$H{$F[0]} += $F[1];END { print $_." ".$H{$_ } for(keys %H)  }' file

Ideone Link

1 голос
/ 28 декабря 2010
$, = ' ';   # set output field separator
$\ = "\n";    # set output record separator

while (<>) {
    ($Fld1,$Fld2) = split(' ', $_, -1);
    $map{$Fld1} += $Fld2;
}

foreach $i (keys %map) {
    print $i, $map{$i};
}

как то так

...