0

Perl 中可以通过 CSV 文件并创建数学计算的最简单代码是什么?
更具体地说:
我有一个 CSV 文件,其中包含:

Input       Execution       Output  Total
608         124800          1856    127264
512         124960          1920    127392
864         124992          1888    127744

我想计算每列的标准偏差。(对于输入\执行\输出\总计)
假设这个文件位于:myDocuments\me\info.csv

我已经成功编写了一个循环 csv 文件并计算列输入的标准偏差的函数。但是,如果我希望它是一个通用函数,我可以从代码中的多个位置调用它,该函数接收诸如“输入”或“执行”之类的字符串,该函数应该对其进行计算 - 我该怎么做?

4

3 回答 3

1

这将做你需要的

use strict;
use warnings;

use List::Util 'sum';

my @data;
while (<DATA>) {
  push @data, [ split ];
}

my $headers = shift @data;
my $n = @data;

for my $i ( 0 .. $#{$data[0]} ) {

  my $mean = sum(map $_->[$i], @data) / $n;
  my $stddev = sqrt(sum(map { ($_->[$i] - $mean) ** 2 } @data) / $n );

  printf "%-9s: Mean %.3f,  Standard Deviation %.3f\n",
      $headers->[$i], $mean, $stddev;
}


__DATA__
Input       Execution       Output  Total
608         124800          1856    127264
512         124960          1920    127392
864         124992          1888    127744

输出

Input    : Mean 661.333,  Standard Deviation 148.569
Execution: Mean 124917.333,  Standard Deviation 83.989
Output   : Mean 1888.000,  Standard Deviation 26.128
Total    : Mean 127466.667,  Standard Deviation 202.947
于 2013-02-25T16:03:18.667 回答
0

大多数人只是使用 拼凑出一个解析器,但是已经存在用于解析和生成 CSV(和制表符分隔的数据)split的快速而强大的轮子。

但是你所问的和你所拥有的似乎是不同的东西。您发布的不是 CSV,Text::CSV_XS 不会这样做。但实际上,这很简单。

您可以使用解析该行

my @fields = split(' ', $line);

您可以使用重新创建文件(如有必要)

printf($fh "%-11d %-15d %-7d %d\n", @fields);

所以你的问题不在于对任意列进行操作。这意味着您需要拥有可以按名称访问的数据列。这对数组的哈希大喊大叫..

 my $headers = <$fh>;
 my @headers = split ' ', $header;

 my %data;
 while (<$fh>) {
    my @row = split;
    for (0..$#header) {
       push @{ $data{ $headers[$_] } }, $row[$_];
    }
 }

 some_func( @{ $data{Execution} } );
于 2013-02-25T15:52:27.363 回答
0
the function is:
 sub parse_standard 
{

    my $filename = "myDocuments\\me\\info.csv";
        #first, calculate the Avg and the number of rows
    open(INPUT, $filename) or die "Cannot open $filename";

    # Read the header line.
    my $line = <INPUT>;
    my $sum = 0 ;
    my $counter = 0;
    #Read the lines one by one.
    while($line = <INPUT>)
    {
        chomp($line);
        my ($Input,$Execution,$Output,$Total,$SelfTest,$Log_Location,$Log_Name) = split(',', $line);
        $sum = $sum + $Input;
        $counter = $counter +1;

    }

    $avg = $sum / $counter ;
#second ,  calculate the standard deviation
    open(INPUT, $filename) or die "Cannot open $filename";
    my $line = <INPUT>;
    my $sum = 0 ;
    #Read the lines one by one.
    while($line = <INPUT>)
    {
        chomp($line);
        my ($Input,$Execution,$Output,$Total,$SelfTest,$Log_Location,$Log_Name) = split(',', $line);
        $diff = ($Input-$avg);      
        $square = $diff * $diff ;       
        $sum = $sum + $square;

    }

    $tosqrt = $sum / $counter;
    $answer = sqrt($tosqrt);
    print "standard deviation is $answer\n";
    close(INPUT);
}

parse_standard();
于 2013-02-25T16:15:27.333 回答