linux - 使用 perl 的标准化方法

标签 linux perl

我正在尝试使用自动化脚本进行标准化(从原始值中减去平均值并除以标准偏差)。 我有一个包含 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/

相关文章:

linux - 如何检查文件是否存在并在不存在时执行命令?

c++ - C 编译 : error: stray '\4' in program ; octal flow?

linux - 在带有屏幕和 nohup 的 Linux 机器上远程运行脚本在注销后不久被终止

perl - 在 Plack 中发送无缓冲响应

linux - 如何在没有密码和公钥的情况下进行 ssh 登录?

c - 如何在没有源代码的情况下判断 Linux 二进制文件创建了多少个线程?

perl - 如何在 Perl 构造函数中定义一个空数组?

regex - perl - 将字符串拆分为 2 个字符的组

perl - 在哈希中打印特定数量的键值对

perl - 使用 Perl 进行格式化输出的最佳方式