2010-11-22 102 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 

keyn(及其值)的key1在csv文件中重複多次。

values(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