2010-11-24 3 views
0

Salut J'ai une grande liste de données: http://paste-it.net/public/y17027d/ C'est 67859 lignes par 10 colonnes. La 6ème colonne contient des valeurs qui représentent des scores Z de 1 à 6 en incréments de 0,01. Ce que je voudrais faire est de totaliser toutes les autres valeurs de colonne qui ont la même valeur Z-score, mais mon code actuel ne fonctionne pas.Besoin d'aide pour réduire une liste et obtenir des totaux en perl

Ce que j'ai maintenant imprimer des valeurs mais les totaux pour chaque Z-Score sont incorrects.
Voici mon code:

#! /usr/bin/perl 

use strict; 
use warnings; 
use POSIX; 
use Data::Dumper; 



my $input = $ARGV[0]; 
open (DATAFILE, $input) or die $!; 
open(OUT,">>"."final.output.txt"); 

my($line,$fMeasure,$filename,$recall,$precision,$z_score,$computer_calls,$johns_calls,$false_negatives,$false_positives,$true_positives,$count); 
$fMeasure=$filename=$recall=$precision=$z_score=$computer_calls=$johns_calls=$false_negatives=$false_positives=$true_positives=$count = 0; 




my %stats=(); 
my %zscore=(); 
while($line = <DATAFILE>){ 
    # Chop off new line character, skip the comments and empty lines.     
    chomp($line); 
    my @temp = split(/\t/, $line); 
    $true_positives = $temp[0]; 
    $false_positives = $temp[1]; 
    $false_negatives = $temp[2]; 
    $johns_calls = $temp[3]; 
    $computer_calls = $temp[4]; 
    $z_score = $temp[5]; 
    $fMeasure = $temp[6]; 
    $precision = $temp[7]; 
    $recall = $temp[8]; 
    $filename = $temp[9]; 
    $stats{$z_score}{$filename}[0] = $true_positives; 
    $stats{$z_score}{$filename}[1] = $false_positives; 
    $stats{$z_score}{$filename}[2] = $johns_calls; 
    $stats{$z_score}{$filename}[3] = $computer_calls; 
    $stats{$z_score}{$filename}[4] = $fMeasure; 
    $stats{$z_score}{$filename}[5] = $precision; 
    $stats{$z_score}{$filename}[6] = $recall; 
    $stats{$z_score}{$filename}[6] = $filename; 
    $zscore{$z_score}++; 

} 


my $false_positives_new = 0; 
my $true_positives_new = 0; 
my $johns_calls_new = 0; 
my $computer_calls_new = 0; 
my $file_name = 0; 


foreach $z_score (sort keys %stats) { 
foreach $filename(keys %{$stats{$z_score}}){ 
    my $tp = $stats{$z_score}{$filename}[0]; 
    my $fp = $stats{$z_score}{$filename}[1]; 
    my $jc = $stats{$z_score}{$filename}[2]; 
    my $cc = $stats{$z_score}{$filename}[3]; 
    my $fn = $stats{$z_score}{$filename}[6]; 
    #print "$z_score\t$jc\n"; 
    $false_positives_new = $false_positives + $fp; 
    $true_positives_new = $true_positives + $tp; 
    $johns_calls_new = $johns_calls + $jc; 
    $computer_calls_new = $computer_calls + $cc; 

    #print OUT "$fn\n"; 
} 

print OUT"$true_positives_new\t$false_positives_new\t$johns_calls_new\t$computer_calls_new\t$z_score \n"; 
$false_positives_new = 0; 
$true_positives_new = 0; 
$johns_calls_new = 0; 
$computer_calls_new = 0; 
$file_name = 0; 

} 



close(OUT); 
close (DATAFILE); 

Je sais que je dois faire quelque chose de mal, mais je ne suis pas en mesure de comprendre quoi. Toute aide serait grandement appréciée. Merci

+0

Qu'est-ce que 'Math :: Complex' faire là-dedans? –

+0

Rien maintenant mais je vais très probablement modifier le programme plus tard et l'exigera. Cela ne devrait cependant pas affecter la fonctionnalité du code. – Alos

+0

J'ai du mal à comprendre comment des nombres complexes viendraient à la tabulation des données, mais de toute façon. –

Répondre

1

Je pense que vous voulez dire

$false_positives_new = $false_positives_new + $fp; 
# etc. 

au lieu de

$false_positives_new = $false_positives + $fp; 
+0

@Alos: J'espère que cela ne signifie pas que vous allez continuer à utiliser ces variables au lieu d'un hachage. –

+0

@Sinan non Je l'ai depuis modifié pour utiliser un hachage. Merci – Alos

2

OK. J'ai été en mesure d'obtenir les données de pastebin et je pense que le code suivant fait ce que vous voulez.

#! /usr/bin/perl 

use strict; use warnings; 
use Data::Dumper; 

my ($input) = @ARGV; 
open my $DATAFILE, '<', $input 
    or die "Cannot open '$input': $!"; 

my @field_names = qw(
    fMeasure 
    recall 
    precision 
    z_score 
    computer_calls 
    johns_calls 
    false_negatives 
    false_positives 
    true_positives 
    count 
); 

my @track_fields = qw(
    false_positives 
    false_negatives 
    johns_calls 
    computer_calls 
); 

my (%stats, %by_zscore); 

while (my $line = <$DATAFILE>) { 
    last unless $line =~ /\S/; 
    chomp $line; 
    my @temp = split /\t/, $line; 
    my $filename = pop @temp; 

    my %fields; 
    @fields{ @field_names } = @temp; 

    my $z_score = $fields{z_score}; 

    $stats{ $z_score }{$filename} = \@temp; 

    for my $f (@track_fields) { 
     $by_zscore{$z_score}{ $f } += $fields{ $f }; 
    } 
} 

print Dumper \%by_zscore; 
Questions connexes