2010-11-22 1 views
1

У меня есть файл csv (очень большой) со следующим форматом.perl вычислять разницу в столбцах в файле csv

key1,val1,val2,val3... ,valn 
key2,val2,val5,val1....,valn 
... 
... 
keyn,val7,val9,val11....,valn 
key1,val2,val4,val8.....,valn 
key2,val10,val12,val14..., valn 
... 
... 
keyn,val2,val4,val8.....,valn 
key1,val3,val5,val7... ,valn 
key2,val0,val9,val3....,valn 

key1 to keyn (и их значения) повторяется несколько раз в файле csv.

значения (val1, valn) являются double (float).

то, что я хочу, чтобы напечатать:

1) С самого начала файла, для каждого ключа я хочу, чтобы вычислить разницу между значениями столбцов (val2, val4, val6, например) к следующему вхождению ключа ,

так, например

key1,2,4,6 
key2,3,5,7 
... 
... 
key1,4,6,8 
key2,4,6,8 

Я хочу напечатать

key1: Diff из предыдущей записи является key1,2,2,2 key2: Diff из предыдущей записи является key2,1,1, 1 ..

Keyn: Diff из предыдущей записи является ...........

2) Сделайте это несколько раз в течение каждого последовательных появлений о f каждый ключ.

Вот что я придумал, чтобы (хранящих значения в хэш)

#!/usr/bin/perl 

my %hash; 
open my $fh, '<', 'file1.csv' or die "Cannot open: $!"; 
while (my $line = <$fh>) { 
    $line =~ s/\s*\z//; 
    my @array = split /,/, $line; 
    my $key = shift @array; 
    $hash{$key} = \@array; 
} 
close $fh; 
+0

жаль ... за плохой идентификатор - :) это был быстрый пост ... у меня действительно есть адрес электронной почты – 2010-11-22 17:50:37

+0

@mystery_man Я думаю, вы в хорошей компании http://en.wikipedia.org/wiki/Austin_Powers:_International_Man_of_Mystery. Что еще более важно, вы не очень хорошо объяснили свою проблему. – 2010-11-22 17:56:57

+0

Это чувствует себя знакомым. Домашнее задание? – 2010-11-22 18:02:05

ответ

0

Моя попытка:

use strict; 
use warnings; 

use Text::CSV_XS; 

use Math::Matrix; 



my $csv = Text::CSV_XS->new({binary => 1}); 

my %hash; 

my @results; 

open my $fh, '<', 'file1.csv' or die "Cannot open: $!"; 

while (my $line = <$fh>) { 

    if ($csv->parse($line)) { 

    my @array = $csv->fields; 
    my $key = shift @array; 

    if (! exists $hash{$key}) { 
     $hash{$key} = \@array; 
     next; 
    } 



    my $previous_record = Math::Matrix->new($hash{$key}); 
    my $current_record = Math::Matrix->new(\@array); 

    my $new_record = $previous_record->add($current_record->negative); 

    push @results, @$new_record; 

    $hash{$key} = \@array; 



    } 
    else { 
    my $err = $csv->error_input; 
    print "error parsing: $err\n"; 
    } 

} 
2

Вы можете попробовать сделать:

# get the key. 
    my $key = shift @array; 

    # see if the key is already seen. 
    if(exists $hash{$key}) { 
      # get ref to previous record of this key. 
      my $ref = $hash{$key}; 

      # print key. 
      print "$key,"; 

      # a new array. 
      my @new_array; 

      # populate the new array. 
      for(my $i=0;$i<=$#array;$i++) { 
        $new_array[$i] = $array[$i] - $$ref[$i]; 
      } 

      # join the array elements with comma. 
      print join",",@new_array; 
      print "\n"; 
    } 

    # add/replace the current array as value for the current key. 
    $hash{$key} = \@array; 

You can see the working code here