如何使用Perl对文本文件中的各个列进行汇总?

如何使用Perl对文本文件中的各个列进行汇总?,perl,Perl,我有这种格式的大型文本文件,希望对这些数字进行统计分析,首先添加列(忽略第一行)。我试着查看其他示例并修改它们,但我的编程很差!所以我想知道是否有人能给我指出正确的方向,谢谢 AF3 F7 F3 FC5 T7 P7 O1 O2 P8 T8 FC6 4464.62 4285.13 4503.59 4505.64 4455.9 4341.03 4257.95 4306.67 4299.49 4180

我有这种格式的大型文本文件,希望对这些数字进行统计分析,首先添加列(忽略第一行)。我试着查看其他示例并修改它们,但我的编程很差!所以我想知道是否有人能给我指出正确的方向,谢谢

AF3     F7      F3      FC5     T7      P7      O1      O2      P8      T8      FC6 
4464.62 4285.13 4503.59 4505.64 4455.9  4341.03 4257.95 4306.67 4299.49 4180    4461.54 
4473.85 4288.72 4510.26 4508.72 4455.38 4347.18 4265.64 4318.97 4310.26 4184.1  4468.21 
4474.87 4289.74 4516.92 4510.77 4450.26 4345.13 4272.82 4332.82 4312.82 4188.72 4464.62

这是一个基本脚本,它为您提供一个列求和的数组。还保留标题。输出以制表符分隔。因为我不知道输入文件的格式,所以我只使用空格

用法:

$ script.pl input.txt > output.txt
use strict;
use warnings;
use ARGV::readonly;

my @data;
my @headers = split ' ', <>;

while (<>) {
    my @row = split;
    $data[$_] += $row[$_] for (0 .. $#row);
}

$" = "\t";
print "@headers", "\n";
print "@data";
AF3     F7      F3      FC5     T7      P7      O1      O2      P8      T8
FC6
13413.34        12863.59        13530.77        13525.13        13361.54
13033.34        12796.41        12958.46        12922.57        12552.82
13394.37
代码:

$ script.pl input.txt > output.txt
use strict;
use warnings;
use ARGV::readonly;

my @data;
my @headers = split ' ', <>;

while (<>) {
    my @row = split;
    $data[$_] += $row[$_] for (0 .. $#row);
}

$" = "\t";
print "@headers", "\n";
print "@data";
AF3     F7      F3      FC5     T7      P7      O1      O2      P8      T8
FC6
13413.34        12863.59        13530.77        13525.13        13361.54
13033.34        12796.41        12958.46        12922.57        12552.82
13394.37

这是一个基本脚本,它为您提供一个列求和的数组。还保留标题。输出以制表符分隔。因为我不知道输入文件的格式,所以我只使用空格

用法:

$ script.pl input.txt > output.txt
use strict;
use warnings;
use ARGV::readonly;

my @data;
my @headers = split ' ', <>;

while (<>) {
    my @row = split;
    $data[$_] += $row[$_] for (0 .. $#row);
}

$" = "\t";
print "@headers", "\n";
print "@data";
AF3     F7      F3      FC5     T7      P7      O1      O2      P8      T8
FC6
13413.34        12863.59        13530.77        13525.13        13361.54
13033.34        12796.41        12958.46        12922.57        12552.82
13394.37
代码:

$ script.pl input.txt > output.txt
use strict;
use warnings;
use ARGV::readonly;

my @data;
my @headers = split ' ', <>;

while (<>) {
    my @row = split;
    $data[$_] += $row[$_] for (0 .. $#row);
}

$" = "\t";
print "@headers", "\n";
print "@data";
AF3     F7      F3      FC5     T7      P7      O1      O2      P8      T8
FC6
13413.34        12863.59        13530.77        13525.13        13361.54
13033.34        12796.41        12958.46        12922.57        12552.82
13394.37

如果你所追求的就是这个总数,那么它就足够可靠了


但是如果计划是实现更多的统计功能,为什么要重新发明轮子呢?是一个Perl模块的存储库,社区已经将这些模块组合在一起。更有可能的是,有人已经编写了一个模块来执行与您所追求的相同的功能

它(理想情况下)允许您更多地关注于满足您的需求,而不是编写代码

虽然我个人对CPAN上可用的模块不满意,但它似乎很好地满足了这个问题的迫切需要


曾几何时,我曾经被从CPAN安装模块的想法吓坏了。以下是一些让您开始的步骤

检查模块是否已安装

$ perl -e 'use Statistics::Descriptive;'
如果安装了它,您将看不到任何输出。如果没有,Perl将抱怨:

在@INC中找不到Statistics/description.pm

BEGIN失败--编译在-e第1行中止

安装模块(如果尚未安装)

使用该模块(假设安装成功)


笔记
我反对使用CPAN解决这里概述的简单问题;这简直是矫枉过正。但当你开始深入研究统计炼金术时,它可能会比你想象的节省更多的时间。

如果你所追求的就是总和,那么它就足够可靠了


但是如果计划是实现更多的统计功能,为什么要重新发明轮子呢?是一个Perl模块的存储库,社区已经将这些模块组合在一起。更有可能的是,有人已经编写了一个模块来执行与您所追求的相同的功能

它(理想情况下)允许您更多地关注于满足您的需求,而不是编写代码

虽然我个人对CPAN上可用的模块不满意,但它似乎很好地满足了这个问题的迫切需要


曾几何时,我曾经被从CPAN安装模块的想法吓坏了。以下是一些让您开始的步骤

检查模块是否已安装

$ perl -e 'use Statistics::Descriptive;'
如果安装了它,您将看不到任何输出。如果没有,Perl将抱怨:

在@INC中找不到Statistics/description.pm

BEGIN失败--编译在-e第1行中止

安装模块(如果尚未安装)

使用该模块(假设安装成功)


笔记
我反对使用CPAN解决这里概述的简单问题;这简直是矫枉过正。但是,当您开始深入研究统计炼金术时,它可能会比您想象的节省更多的时间。

对于数组操作,Perl具有MatLab或IDL的特性

PDL创建和使用示例:

#!/usr/bin/env perl

use strict;
use warnings;

use PDL;

use Scalar::Util 'looks_like_number';

# get data into proper format
# N.B. fast and dirty method
my $line_number = 0;
my @data;
while(<DATA>) {
  $line_number++;

  #ignore whitespace or empty lines
  next if /^\s*$/;

  my @line = split;

  #ignore lines with non-numeric data
  if ( grep { ! looks_like_number $_ } @line ) {
    print "line $line_number contains non-numeric data, skipping\n";
    next;
  }

  push @data, \@line;
}

#create PDL object (called piddle)
my $pdl = pdl(@data);

print "PDL:\n";
print $pdl;

print "Sum columns:\n";
#sumover acts on 0th dim, so "transpose" 0 and 1
print sumover $pdl->xchg(0,1);


__DATA__
AF3     F7      F3      FC5     T7      P7      O1      O2      P8      T8      FC6 
4464.62 4285.13 4503.59 4505.64 4455.9  4341.03 4257.95 4306.67 4299.49 4180    4461.54 
4473.85 4288.72 4510.26 4508.72 4455.38 4347.18 4265.64 4318.97 4310.26 4184.1  4468.21 
4474.87 4289.74 4516.92 4510.77 4450.26 4345.13 4272.82 4332.82 4312.82 4188.72 4464.62
#/usr/bin/env perl
严格使用;
使用警告;
使用PDL;
使用Scalar::Util“看起来像数字”;
#将数据转换成适当的格式
#注意:快速脏法
我的$line_编号=0;
我的@数据;
while(){
$line_number++;
#忽略空白或空行
下一个if/^\s*$/;
我的@line=split;
#忽略包含非数字数据的行
if(grep{!看起来像\u number$\u}@line){
打印“行$line\u编号包含非数字数据,跳过\n”;
下一个
}
按@数据,\@行;
}
#创建PDL对象(称为piddle)
my$pdl=pdl(@data);
打印“PDL:\n”;
打印$pdl;
打印“总和列:\n”;
#sumover作用于第0个dim,因此“转置”0和1
打印金额超过$pdl->xchg(0,1);
__资料__
AF3 F7 F3 FC5 T7 P7 O1 O2 P8 T8 FC6
4464.62 4285.13 4503.59 4505.64 4455.9  4341.03 4257.95 4306.67 4299.49 4180    4461.54 
4473.85 4288.72 4510.26 4508.72 4455.38 4347.18 4265.64 4318.97 4310.26 4184.1  4468.21 
4474.87 4289.74 4516.92 4510.77 4450.26 4345.13 4272.82 4332.82 4312.82 4188.72 4464.62
当然,您很可能正在从文件加载数据,因此,您不必在
上循环,而应该在某些文件句柄上循环

创建对象后,函数(如
sumover
或中的函数)可以为您做腿部工作

安装时:
我有一篇关于Ubuntu的帖子,否则请查看。

关于Perl的数组操作,它与MatLab或IDL类似

PDL创建和使用示例:

#!/usr/bin/env perl

use strict;
use warnings;

use PDL;

use Scalar::Util 'looks_like_number';

# get data into proper format
# N.B. fast and dirty method
my $line_number = 0;
my @data;
while(<DATA>) {
  $line_number++;

  #ignore whitespace or empty lines
  next if /^\s*$/;

  my @line = split;

  #ignore lines with non-numeric data
  if ( grep { ! looks_like_number $_ } @line ) {
    print "line $line_number contains non-numeric data, skipping\n";
    next;
  }

  push @data, \@line;
}

#create PDL object (called piddle)
my $pdl = pdl(@data);

print "PDL:\n";
print $pdl;

print "Sum columns:\n";
#sumover acts on 0th dim, so "transpose" 0 and 1
print sumover $pdl->xchg(0,1);


__DATA__
AF3     F7      F3      FC5     T7      P7      O1      O2      P8      T8      FC6 
4464.62 4285.13 4503.59 4505.64 4455.9  4341.03 4257.95 4306.67 4299.49 4180    4461.54 
4473.85 4288.72 4510.26 4508.72 4455.38 4347.18 4265.64 4318.97 4310.26 4184.1  4468.21 
4474.87 4289.74 4516.92 4510.77 4450.26 4345.13 4272.82 4332.82 4312.82 4188.72 4464.62
#/usr/bin/env perl
严格使用;
使用警告;
使用PDL;
使用Scalar::Util“看起来像数字”;
#将数据转换成适当的格式
#注意:快速脏法
我的$line_编号=0;
我的@数据;
while(){
$line_number++;
#忽略空白或空行
下一个if/^\s*$/;
我的@line=split;
#忽略包含非数字数据的行
if(grep{!看起来像\u number$\u}@line){
打印“行$line\u编号包含非数字数据,跳过\n”;
下一个
}
按@数据,\@行;
}
#创建PDL对象(称为piddle)
my$pdl=pdl(@data);
打印“PDL:\n”;
打印$pdl;
打印“总和列:\n”;
#sumover作用于第0个dim,因此“转置”0和1
打印金额超过$pdl->xchg(0,1);
__资料__
AF3 F7 F3 FC5 T7 P7 O1 O2