2011-11-25 94 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

相關問題