我有这种格式的大文本文件,并希望对这些数字进行统计分析,首先添加列(忽略第一行)。我试过看其他例子并修改它们但我的编程很差!所以我想知道是否有人能指出我正确的方向,谢谢!
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
答案 0 :(得分:4)
这是一个基本脚本,它为您提供了一个总和列的数组。还保留标题。输出以制表符分隔。由于我不知道输入文件的格式,我只是简单地拆分空格。
<强>用法:强>
$ 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
答案 1 :(得分:1)
对于数组操作,Perl有PDL
,这是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
当然你最有可能是从文件加载数据,所以不是循环遍历<DATA>
,而是循环一些文件句柄。
创建对象后,sumover
等函数或PDL::Ufunc
中的函数可以为您完成任务。
安装时: 我在Ubuntu上有installing PDL的帖子,否则请查看the wiki。
答案 2 :(得分:0)
如果总和就是你所追求的,那么TLP's answer就足够了。
但如果计划要实施更多统计功能,为什么要重新发明轮子呢? CPAN是社区放在一起的Perl模块的存储库。更有可能的是,有人已经编写了一个模块来执行您所追求的相同功能。
它(理想情况下)允许您更专注于满足您的需求,而不是更多地编写代码。
虽然我个人对CPAN上的Statistics模块不满意,但似乎Statistics::Descriptive
恰当地满足了这个问题的直接需求。
曾几何时,我常常被必须从CPAN安装模块的想法吓到了。以下是帮助您入门的几个步骤。
检查模块是否已安装
$ perl -e 'use Statistics::Descriptive;'
如果已安装,您将看不到输出。如果没有,Perl会抱怨:
无法在@INC中找到Statistics / Descriptive.pm ...
BEGIN失败 - 编译在-e第1行中止。
安装模块(如果已经存在)
$ cpan Statistics::Descriptive
使用模块(假设安装成功)
use strict;
use warnings;
use Statistics::Descriptive;
我反对将CPAN用于此处列出的简单问题;这简直太过分了。但是,当你开始深入研究统计炼金术时,它可能比你想象的节省更多的时间。
答案 3 :(得分:0)
PDL-2.4.7 rcols
可用于读取列数据,包括文件第一行的列ID。然后可以使用PDL sumover
例程如上计算总和:
use strict;
use warnings;
use PDL;
my $hdr = [];
my $pdl = rcols( \*DATA, [], { colids=>$hdr } );
print "PDL:\n";
print $pdl;
print "Column IDs: @{$hdr}\n";
print "Sum columns:\n";
print sumover $pdl;
__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
有关详细信息,请参阅PDL web page。 perldl mailing list通常是提问或与PDL开发人员或用户社区交互的最佳方式。请尝试help rcols
shell中的pdl2
获取所有rcols
功能的文档。
答案 4 :(得分:0)
perl 在这里是一个不错的选择,但对于像我这样的简单任务,我总是使用已经可用的工具链(在unix上)。
摆脱标题
sed&#39; 2,$!d&#39;
总结第n列
awk&#39; {sum + = $ n}; END {print sum}&#39;
所以这一切,为第三列做这个:
sed '2,$!d' <filename> | awk '{sum += $3}; END {print sum}'
如果您的awk实现截断,这可能会更好:
(awk '{print $3}' <filename> | sed '2,$!d' | tr "\012" "+"; echo "0") | bc
或者这个:
(awk '{print $3}' <filename> | sed '2,$!d' | paste -sd+ -) | bc
(某些粘贴实现需要指定&#39; - &#39;以便从标准输入读取。
e7 v01L4! 13530.77:)
如果你坚持perl,那怎么样:
perl -nle '$sum += $_ } END { print $sum' <filename>
答案 5 :(得分:0)
单线方法:
$ perl -MList::Util=sum -lane 'print sum(@F[1 .. $#F])' < data.txt
0
43596.94
43657.44
43684.62
说明:
perl
:致电Perl,duh; -MList::Util=sum
:从模块List::Util导入sum()
函数,这是默认Perl安装的一部分; -lane
:指定-l -a -n -e
选项的简短方法,其中:
-l
:启用自动行结束处理(在输入上删除换行符,附加在输出上); -a
:启用自动分割模式(默认情况下,将单词 - 非单词边界上的每一行拆分并将结果放入@F
数组中); -n
:迭代输入; -e
:要评估的代码。print sum @F[1 .. $#F]
:最后,Perl代码本身:
print
:不言自明; sum
:ditto; @F[1 .. $#F]
:来自数组@F
的切片,从元素#1开始(第一个元素是#0),直到最后一个元素($#F
是该数组的索引@F
)的最后一个元素。观察:输出的第一行是 0 ,因为Perl将非数字事物(标题)评估为数字0。