我可以转换此Perl脚本以使其从文件中读取吗?

时间:2011-11-25 01:53:58

标签: perl statistics project

我希望使用Perl脚本获取特定数据列的中位数,我得到了一个脚本,它读取脚本中数组的值,。

my (@vals, $med);
@vals =(12, 23, 34, 21, 66,66, 34, 87);
print "UNSORTED: @vals\n"; #sort data points 
@vals = sort(@vals); 
print "SORTED: @vals\n"; #test to see if there are an even number of data points 
if( @vals % 2 == 0) { #if pair then: 
$sum = $vals[(@vals/2)-1] + $vals[(@vals/2)]; 
$med = $sum/2; 
print "The median value is $med\n"; 
} 
else {                       #if odd then: 
print "The median value is $vals[@vals/2]\n"; 
} 
exit;

我可以通过某种方式对其进行转换,使其从多个列的文件中读取数据并计算所选列的中位数吗?比如在shell命令中键入./median.pl 1 column_numbers.tbl。 我试过这个,但文件data.txt只有一列

my (@vals, $med, $sum1, @numbers, @sorted);
open (COLUMN, "< data.txt") || die "Can not open file : $! ";
my @not_sorted = <COLUMN>;                  
close (COLUMN);
@sorted = sort { $a <=> $b } @not_sorted;  
if (@vals % 2 == 0) {  
$med = ($sorted[int($N/2)]);             
print "MEDIAN = $med\n";
}
else {  
$sum1 = $vals[(@vals/2)-1] + $vals[(@vals/2)]; 
$med = $sum1/2;
print "MEDIAN = $vals[@vals/2]\n";
};

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

您对其他列感兴趣吗?如果没有,只需忽略它们。

此程序代码段从文件中读取一行,然后将所需列推送到数组@medium_array。由于大多数人认为第一列是第1列,但Perl认为它是第0列,我添加了一个名为COLUMN_OFFSET的偏移量。

主要工作是通过以下方式完成的:

push @medium_array, (split " ", $line)[$column_for_medium - COLUMN_OFFSET];

此行使用pushsplit命令。在你明白这条线的作用之前不要继续前进。

该程序可以使用一些更好的参数错误检查。用户是否请求列大于文件中的列数?如果文件中不存在列,该怎么办?如果文件不存在怎么办?所有这些东西都应该在这个程序中添加和检查。

最后,该程序将所需的列存储到@medium_array中。从那里,您应该能够使用以前的代码来查找该列的介质。

use strict;
use warnings;
use autodie;

use constant {
    COLUMN_OFFSET => 1,    #Incase you want to number cols from 1 instead of 0
};

# Read in the command line parameters

my $column_for_medium = shift;
my $file_name         = shift;

# Some sort of parameter checking

if (not defined $file_name and not $column_for_medium =~ /^\d+$/) {
   die qq(You must have two parames: "Column Num" and "File Name");
}

open (my $array_file, "<", $file_name);
my @medium_array;
while (my $line = <$array_file>)   {
   chomp $line;
   push @medium_array, (split " ", $line)[$column_for_medium - COLUMN_OFFSET];
}       

答案 1 :(得分:0)

原则上我同意TLP的意见,但因为我现在没有发现其他任何对我感兴趣的问题:

#!/usr/bin/perl

use strict;
use warnings;

my $index = shift;
my $filename = shift;
my $columns = [];

open (my $fh, "<", $filename) or die "Unable to open $filename for reading\n";

for my $row (<$fh>) {

    my @vals = split/\s+/, $row;
    push @{$columns->[$_]}, $vals[$_] for 0 .. $#vals;
}

close $fh;

my @column = sort {$a <=> $b} @{$columns->[$index]};

my $offset = int($#column / 2);
my $length = 2 - @column % 2;

my @medians = splice(@column, $offset, $length);

my $median;
$median += $_ for @medians;
$median /= @medians;

print "$median\n";

如果数据是以空格分隔的,则此方法有效。第一个参数是0索引列号,第二个参数是有效文件名。

如果你是perl的新手,我应该注意标量上下文中的数组返回元素的数量,如my $length = 2 - @column % 2;$median /= @medians;