如何在perl中从二进制数据集中选择行和计数值?
我希望你们中的任何人都能帮助我。我有一个类似的数据集: 0100010011 1011100100 0001001100 0101111011 0010000100 1101111011 0000111000 0001000101 1110000010 0001000011 0110111100 1001000001 此示例仅包含四个“段落”,每行三行,每行10位。我的真实数据要大得多,它有1000个段落,每个段落有100行,每行有50个数字,都是二进制数据。 我需要计算每个段落每列出现1的次数。我一直在网上搜索,发现以下代码:如何在perl中从二进制数据集中选择行和计数值?,perl,selection,grouping,sum,Perl,Selection,Grouping,Sum,我希望你们中的任何人都能帮助我。我有一个类似的数据集: 0100010011 1011100100 0001001100 0101111011 0010000100 1101111011 0000111000 0001000101 1110000010 0001000011 0110111100 1001000001 此示例仅包含四个“段落”,每行三行,每行10位。我的真实数据要大得多,它有1000个段落,每个段落有100行,每行有50个数
#!/usr/bin/perl
my @LineTotalsArray;
while (my $line = <stdin>) {
print $line;
chomp $line;
my $index=0;
for my $val ( split /\t/, $line ) {
$LineTotalsArray[ $index++ ] += $val;
}
}
print join('=', @LineTotalsArray), "\n";
这适用于所有文件,它不区分段落,因此它为我提供了整个数据集中每列1个的总说明:45456
0100010011
1011100100
0001001100
0101111011
0010000100
1101111011
0000111000
0001000101
1110000010
0001000011
0110111100
1001000001
4547555556
你们有谁知道我在这种情况下能做什么吗?在perl中,我如何判断我希望每三行执行一次此操作
谢谢您的帮助,欢迎您提出任何建议
#!/usr/bin/perl
my @LineTotalsArray;
while (my $line = <stdin>) {
print $line;
chomp $line;
my $index=0;
chomp;
my @val = (split /\t/, $line);
if (@val <= 1) {
print "=", join('=', @LineTotalsArray), "\n";
@LineTotalsArray = undef;
}
else {
for my $val ( split /\t/, $line ) {
$LineTotalsArray[ $index++ ] += $val;
}
}
}
print "=", join('=', @LineTotalsArray), "\n";
以空行结束。您需要打印结果并在每个空行上清理数组。有很多方法可以检查chomp、regexp“^$”等之后的空行0长度。。。我可能会执行零长度,但这只是对代码的快速更改
use strict;
use warnings;
use 5.010;
use Data::Dumper;
my %totals;
{
$/ = "\n\n";
while (my $chunk = <DATA>) {
chomp $chunk;
my @line_totals;
for my $line (split /\n/, $chunk) {
my $index = 0;
for (split //, $line ) {
$line_totals[$index++] += $_;
}
}
say $chunk;
say @line_totals, "\n";
$totals{$chunk} = join '', @line_totals;
}
}
say Dumper \%totals;
这仅在数据已经分块的情况下有效,如您的示例中所示。我们设置了一条双换行线;在那之后,我们需要将这些块分割成几行,然后将这些行分割成我们一起求和的部分
如果可以的话,我自己的一个子问题是:有人能想出一个使用vec的解决方案吗
编辑:我一直在想我是否可以用正则表达式来完成内部部分。以下是我无力的尝试:
{
$/ = "\n\n";
while (<DATA>) {
chomp;
our @lines_total = ();
my $index = 0;
() = /(?
(?<=^)
([0-1])(?{ $index = 0; $lines_total[$index] += $^N })
|
([0-1])(?{ $lines_total[++$index] += $^N })
)/xmg;
say join '', @lines_total;
}
}
因为一个错误,我不得不使用我们的。如果输入数据集不在块中,将在perlre中解释:
#!/usr/bin/perl
use strict; use warnings;
use YAML;
my @counts;
my $every_n = 3;
while (my $row = <DATA>) {
last unless my @digits = $row =~ /([01])/g;
$counts[($. - 1) / $every_n][$_] += $digits[$_] for 0 .. $#digits;
}
print Dump \@counts;
__DATA__
0100010011
1011100100
0001001100
0101111011
0010000100
1101111011
0000111000
0001000101
1110000010
0001000011
0110111100
1001000001
#!/usr/bin/perl
use strict; use warnings;
use YAML;
my @counts;
{
local $/ = "";
while ( my $chunk = <DATA> ) {
while ( $chunk =~ /([01]+)/g ) {
my @digits = $1 =~ /([01])/g;
$counts[$. - 1][$_] += $digits[$_] for 0 .. $#digits;
}
}
}
print Dump \@counts;
__DATA__
0100010011
1011100100
0001001100
0101111011
0010000100
1101111011
0000111000
0001000101
1110000010
0001000011
0110111100
1001000001
如果输入数据集已在块中:
#!/usr/bin/perl
use strict; use warnings;
use YAML;
my @counts;
my $every_n = 3;
while (my $row = <DATA>) {
last unless my @digits = $row =~ /([01])/g;
$counts[($. - 1) / $every_n][$_] += $digits[$_] for 0 .. $#digits;
}
print Dump \@counts;
__DATA__
0100010011
1011100100
0001001100
0101111011
0010000100
1101111011
0000111000
0001000101
1110000010
0001000011
0110111100
1001000001
#!/usr/bin/perl
use strict; use warnings;
use YAML;
my @counts;
{
local $/ = "";
while ( my $chunk = <DATA> ) {
while ( $chunk =~ /([01]+)/g ) {
my @digits = $1 =~ /([01])/g;
$counts[$. - 1][$_] += $digits[$_] for 0 .. $#digits;
}
}
}
print Dump \@counts;
__DATA__
0100010011
1011100100
0001001100
0101111011
0010000100
1101111011
0000111000
0001000101
1110000010
0001000011
0110111100
1001000001
谢谢它起作用了。我只需要在最后一段中稍微修改一下