2011-11-25 100 views
-2

我想使用Perl脚本来获取特定数据列的中位数,我得到一个脚本,读取脚本中数组的值。我可以转换此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"; 
}; 

感谢您的帮助。

+1

是的,你可以!只是告诉我们你已经尝试了什么,所以我们可以帮助你。 – gangabass

+4

在我看来,你已经问过这个问题了...... 4或5次左右。这不是一个为我写代码的网站,当你遇到麻烦时,你必须付出努力并提出具体问题。在[perldoc.perl.org](http://perldoc.perl.org)上有文档可以找到。 'perlopen'和它的关联文件可能是一个很好的开始。 – TLP

+0

这是我之前询问的一部分,我尝试并修复了大部分问题。如果你不想回答我的问题,你是免费的,但不要责怪我不努力。谢谢 – Dav1

回答

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;

+0

非常感谢。你是对的,我是perl的新成员,每天都在努力改善,但很高兴找到像你这样的人,人们在学习问题时不停地学习,不要放弃。你脚本给我我正在寻找的结果,现在我要去做其余的... +1000代表。 ;) – Dav1

0

你对其他专栏感兴趣吗?如果不是,则简单地忽略它们。

该程序片段从文件读取一行,然后将想要的列推入数组@medium_array。由于大多数人认为第一列是第一列,但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]; 
}  
+0

非常感谢!Idea的想法是以第一列为例,然后在需要时使用其他列。例如./script.pl 1 columns.tbl或./script.pl 7 columns.tbl或./script。pl“1:7”columns.tbl ... – Dav1

+0

这可能吗? – Dav1

+0

我有这个错误..不允许使用Bareword“FILE_NAME”,而在./open_file.pl行中使用“strict subs”。22.有什么问题? – Dav1

相关问题