我正在尝试使用自动化脚本进行标准化(从原始值中减去平均值并除以标准偏差)。 我有一个包含 10000 行的文件。我需要先计算每一列的平均值和标准差,然后使用这些值我必须获得新的标准化值。我可以在 excel 中很容易地做到这一点。但我正在寻找一个自动化脚本。
输入
DOTR1 10.29006 10.06744 10.47105 10.05041 10.18407 9.770205 10.90548 10.75112
RCC2 6.699481 7.240353 7.263434 6.654058 6.86063 7.151931 6.796337 6.78525
HHPA6 7.31182 7.547056 8.338827 7.278408 7.545548 7.409964 7.149899 7.300342
PAX8 8.336847 8.651292 8.493323 8.5056 8.445139 8.651406 8.664237 8.56571
ACA1A 4.233111 4.320666 4.232803 4.390224 4.269969 4.314899 4.264211 4.142419
UBA7 8.196608 8.164725 7.361889 8.055019 8.882745 7.6884 7.835754 8.354209
OOA 5.098222 5.212986 5.301191 5.211401 5.13133 5.153725 5.269111 5.195991
ACX1 4.875679 5.01305 4.921618 4.930978 4.899562 4.92918 4.970339 4.986362
第 1 列的平均值为 6.880,标准差为 2.066
我现在将从我的观察中减去均值,然后除以标准偏差为 (10.29006-6.880)/2.066。我将对第 1 列中的所有后续观察按行执行此操作。对于第 2 列,我将再次找到它的均值和相应的标准差,并遵循相同的过程。
谢谢,
我尝试了以下代码来获取 avg 和 stdev..我无法继续下一步..
sub average{
my($data) = @_;
if (not @$data) {
die("Empty array\n");
}
my $total = 0;
foreach (@$data) {
$total += $_;
}
my $average = $total / @$data;
return $average;
}
sub stdev{
my($data) = @_;
if(@$data == 1){
return 0;
}
my $average = &average($data);
my $sqtotal = 0;
foreach(@$data) {
$sqtotal += ($average-$_) ** 2;
}
my $std = ($sqtotal / (@$data-1)) ** 0.5;
return $std;
}
最佳答案
只用数组的数组来表示表格。逐列查看表格,获取平均值和标准差,然后替换列中的每个值。
#!/usr/bin/perl
use warnings;
use strict;
open my $IN, '<', 'input' or die $!;
my @table;
while (<$IN>) {
$table[$. - 1] = [ split ];
}
for my $column (1 .. $#{ $table[0] }) {
my $total = 0;
$total += $_ for map $table[$_][$column], 0 .. $#table;
my $mean = $total / @table;
my $sqtot = 0;
$sqtot += ($mean - $_) ** 2 for map $table[$_][$column], 0 .. $#table;
my $stdev = ($sqtot / $#table) ** 0.5;
$table[$_][$column] = ($table[$_][$column] - $mean) / $stdev for 0 .. $#table;
}
$\ = "\n";
for my $line (@table) {
print join "\t", @$line;
}
关于linux - 使用 perl 的标准化方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14612332/