如何在perl中从二进制数据集中选择行和计数值?

如何在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个数

我希望你们中的任何人都能帮助我。我有一个类似的数据集:

0100010011 1011100100 0001001100 0101111011 0010000100 1101111011 0000111000 0001000101 1110000010 0001000011 0110111100 1001000001 此示例仅包含四个“段落”,每行三行,每行10位。我的真实数据要大得多,它有1000个段落,每个段落有100行,每行有50个数字,都是二进制数据。 我需要计算每个段落每列出现1的次数。我一直在网上搜索,发现以下代码:

#!/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

谢谢它起作用了。我只需要在最后一段中稍微修改一下