我希望使用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";
};
感谢您的帮助。
答案 0 :(得分:0)
您对其他列感兴趣吗?如果没有,只需忽略它们。
此程序代码段从文件中读取一行,然后将所需列推送到数组@medium_array
。由于大多数人认为第一列是第1列,但Perl认为它是第0列,我添加了一个名为COLUMN_OFFSET
的偏移量。
主要工作是通过以下方式完成的:
push @medium_array, (split " ", $line)[$column_for_medium - COLUMN_OFFSET];
此行使用push
和split
命令。在你明白这条线的作用之前不要继续前进。
该程序可以使用一些更好的参数错误检查。用户是否请求列大于文件中的列数?如果文件中不存在列,该怎么办?如果文件不存在怎么办?所有这些东西都应该在这个程序中添加和检查。
最后,该程序将所需的列存储到@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;
。