5

经过大约 6 个月的重大休息后,我回到了 Perl 和生物信息学的世界,在另一位科学家手下实习。但是第一个任务不同于我上次遇到的任何任务,所以虽然我取得了一些进展,但我还没有能够完全解决这个问题。我还试图尽快修改我上次学到的任何东西,因为在过去的 6 个月里我完全失去了编程的联系。数据集如下所示:

NR_046018   DDX11L1     ,   0   0   1   1   1   1   1   1   1   1   0   0   0   0   1.44    2.72    3.84    4.92    5.6 6.64    7.08    9.12    9.56    8.28    7.16    6.08    5.4 4.36    3.92    1.88    0   0   0.76    1   1   1   1.2 2   2   2   1.72    2   2   2   1.8 1   1.88    2.4 3   3.36    5   6   6   6.72    6.12    5.6 5.44    5.56    5   4.04    5   4.28    4   4   3.08    2.08    1.68    1.96    1.44    3   3.68    4   4.16    5   4.32    4.8 6.16    6   6.28    6.92    7.84    7   7.32    7.2 5.96    5   4.52    4.08    3   3   4.04    4.12    4.44    4   3.52    3.4 4   4   2.64    1.88    1   1   1   0.64    1   1   1.24    2   2.92    3   3   2.96    2   2   2.56    2   1.08    2.12    3   3   3   3   2.6 3   4.64    3.88    3.72    4   4   4.96    4.6 4   2.36    2   1.28    1   1   0.04    0   0.24    1.08    2.68    3.84    4.12    5.72    6   6   5.76    4.92    3.32    3.12    2.88    2.08    2   2   2   2   2   1.44    2.92    3.04    4.28    5.8 7.8 9.48    10.52   13.04   12.08   11.6    11.72   11  9.2 7.52    7.12    7.08    7.08    8.32    7   6.6 7.6 8.04    8.36    6.72    7.88    7.72    8.4 9.24    8.88    8.96    9.88    10.08   9.24    9.28    10.16   11.04   10.52   10  8.56    8   7.8 7.72    6.44    4.32    4   4   3.72    3.68    3.68    3.28    5.56    7.36    9.48    10  10.52   11  12.16   11.96   9.44    8.64    7.52    7   6.48    6   5   5.12    6.28    6   5.52    6   6.68    6.08    7.52    8.16    7.72    8.52    8.56    9.2 9.16    8.92    7.44    6   5   3.48    2.92    2.16    2   2   1.2 1   1   1   1.24    1.64    1   1   1.96    2   2   2   1.76    1   1   1   0.52    1.76    3.64    5.12    6   6   6   6   5.52    4.24    2.36    0.88    0   0   0.68    1   1   1   1   1   1   1   0.32    0   0   1   1   1.44    2.44    3.68    5.4 6.88    7   6   6.52    6.76    6.56    5.32    3.6 2.92    3   3.72    3.96    3.8 3   3   3   2.2 2.4 2.28    1.52    1   1   1   1.72    2   1.6 1   1   1   1   1   0.28    0.92    2   2   2.72    3.64    4   4.84    5   4.08    3   3   2.68    2.36    2   1.16    1   1   2   4.92    4.6 4   4   4   4   4.32    4   1.08    1   1.52    2   2   2   1.68    1   1   1.32    1.48    1   1   1.52    2   2   2   1.68    1   1   1.88    1.48    1   1   1   1   1   1   0.12    0.4 1   1   1.2 3.88    4   5   5   4.6 4   4   3.8 2.08    2   1   1   1.44    2.4 3
NR_047520   LOC643837   ,   3   2.2 0.2 0   0   0.28    1   1   1   1   2.2 4.8 5   5.32    5   5   5   5   3.8 1.2 1   0.4 0   0   0   0   0   1   1   1   1   1   1   1   1.56    1   1   1   1   1   1   1   0.44    0.68    1   1.52    3   3.6 4.96    6.8 9   8.32    8.72    8.48    7   7.4 8.8 7.92    7.12    8.84    8.56    9.4 10.2    10  7.24    6.44    6.76    6.16    5.72    4.96    4.8 5.16    6   5.84    4.12    3   3   2.64    2.56    3.08    3   4.16    5   6.72    7   7.16    7.44    5.76    5   4.56    4   3.68    5   5.4 5.52    6   6   5.28    5   3.6 2   2.08    1.48    1   2   2   2   2   2   1.36    1   1   0   0   0.68    1   1   1   1   1   1   1   0.32    0   0   0   1.16    2   2   2   2   2.88    3   3   1.84    1   2   2   2.04    2.12    2   2   2   2   1   1.28    1.96    1.36    2.76    3   3   3   3   2.72    2   1.64    0.76    1   1.36    2   2   2   2   2   1.48    1   0.64    0   0.08    1   1   1.08    2   2   2   2   2.68    2   2   2.16    3.4 4   4   4.2 4.24    4   5.68    6.52    4.6 4   4   3.8 3.8 4   3.12    2.24    2.6 3   4   4   3.2 3   2.2 2   1.4 1.84    1.24    2   2   2   2   2   2   1.16    0.76    0   0   0   0   0   0   0   0.36    1   1.68    2   2   2.92    5.4 6.76    7.64    7   6.88    7   7.36    7.92    6.24    5.92    7.04    9.52    11.52   12.88   14.8    16.36   19.88   22.24   20  19.36   16.92   15.24   13.84   10.88   8.24    5.08    4.96    3.12    3   2.88    2   2.8 2.96    4   4.44    5   6   6   6   5.12    3.28    2   1.56    1   0.08    1.68    2   2   2.84    3   3   3.8 3.92    2.32    2   2.2 2.16    2   2   1.2 1   1   1   0.8 0   0   0   0.72    2.88    3   3   3   3   3   3   2.28    0.12    0   0.52    1   1   1   1   1.44    2   2   1.48    1   1   1   1.56    1.56    1   1   1   1   1   1   0.44    0.8 1.48    3   3   3   3   3   3.56    3.2 2.76    2   2   2   2   2.68    2.44    2   1.76    1   1.4 2   2   1.56    2   2   2   2   2.04    2   2   1.76    1   1   1   1   0.56    0   0   0   0   0   0   0   0   0.72    1.52    2   2   2   2   2   2   1.28    0.48                                                                            

1. 需要什么

  1. 对于数据文件中的每一行,从数字范围中找到最大值。
  2. 找到所有行的最大值后,找到平均最大值。

2. 我在想的策略

  1. 将非数字部分与非数字部分分离为哈希的“键”
  2. 将数字部分放入哈希的“值”中。
  3. “值”分配到数组中@values
  4. 使用模块use List::Util qw(max)从数组中找到最大值
  5. 将这些最大值存储在另一个数组中并从该数组中找到平均值。

3. 目前写的代码

use warnings;
use List::Util qw(max);

#Input filename
$file = 'test1.data';

#Open file
open I, '<', $file or die;

#Separate data into keys and values, based on ','
chop (%hash = map { split /\s*,\s*/,$_,2 } grep (!/^$/,<I>));
print "$_ => $hash{$_}\n" for keys %hash; #Code is working fine till here

#Create a values array
@values = values %hash;
foreach $value(@values){
 print "The values are : ", $value,"\n";
}

4.问题

除此之外,我无法弄清楚如何将每个"individual"数组元素添加到一个新数组中,以便我可以使用 max 函数。

我的意思是,例如,first array elementin@values包含像0 0 1 1 3 4.4. second array element可能有类似的数据3 2.2 0.28 1 1 4.8。所以我需要将each这些数组元素放入一个新数组中,每个元素放入一个不同的数组中,以便我可以使用该max函数。

五、注意事项

  1. 大多数行包含 400 个数字,有些行少于 400 个,但从不超过 400 个。

  2. 总共有 23,558 行。

  3. 文件是一个 .txt 文件,每行中的所有数字都是制表符分隔的。

如果有人愿意为我指出正确的方向,或者提供更好的代码来解决1 中提到的问题,我将不胜感激。

4

2 回答 2

7

如果我正确理解了您的问题,那么您将使它变得过于复杂:

#!/usr/bin/env perl
use strict;
use warnings;
use List::Util qw(max);

#Input filename
my $file = 'test1.data';

#Open file
open my $fh, '<', $file or die "Unable to open $file: $!\n";

my ($total, $num);

while (<$fh>) {
    my @values = split;
    my $max = max(@values[3 .. $#values]);
    $total += $max;
    $num++;
}

my $average_max = $total / $num;

只需对您的文件进行一次传递,将行拆分为一个数组并将所有内容从 index 馈送3max. 添加$max$total每一行,增加一个计数器 ( $num) 并从中计算平均最大值。

您还应该始终使用use strict和词法文件句柄。

于 2012-12-19T09:57:03.697 回答
1

这是一个有趣的解决方案。如果你正在使用List::Util,你不妨也使用sum

#!usr/bin/perl
use strict;
use warnings;
use List::Util qw/max sum/;

my %line_max = map {
    /([\w\s]*?)\s*,\s*(.*)/ or die "bad line";
    $1 => max split ' ', $2
} <DATA>;

print "$_: $line_max{$_}\n" foreach (keys %line_max);

my $avg_max = sum (values %line_max) / scalar (values %line_max);
print "average: $avg_max\n";

__DATA__
NR_046018   DDX11L1     ,   0   0   1   1   1   1   1   1   1   1   0   0   0   0   1.44    2.72    3.84    4.92    5.6 6.64    7.08    9.12    9.56    8.28    7.16    6.08    5.4 4.36    3.92    1.88    0   0   0.76    1   1   1   1.2 2   2   2   1.72    2   2   2   1.8 1   1.88    2.4 3   3.36    5   6   6   6.72    6.12    5.6 5.44    5.56    5   4.04    5   4.28    4   4   3.08    2.08    1.68    1.96    1.44    3   3.68    4   4.16    5   4.32    4.8 6.16    6   6.28    6.92    7.84    7   7.32    7.2 5.96    5   4.52    4.08    3   3   4.04    4.12    4.44    4   3.52    3.4 4   4   2.64    1.88    1   1   1   0.64    1   1   1.24    2   2.92    3   3   2.96    2   2   2.56    2   1.08    2.12    3   3   3   3   2.6 3   4.64    3.88    3.72    4   4   4.96    4.6 4   2.36    2   1.28    1   1   0.04    0   0.24    1.08    2.68    3.84    4.12    5.72    6   6   5.76    4.92    3.32    3.12    2.88    2.08    2   2   2   2   2   1.44    2.92    3.04    4.28    5.8 7.8 9.48    10.52   13.04   12.08   11.6    11.72   11  9.2 7.52    7.12    7.08    7.08    8.32    7   6.6 7.6 8.04    8.36    6.72    7.88    7.72    8.4 9.24    8.88    8.96    9.88    10.08   9.24    9.28    10.16   11.04   10.52   10  8.56    8   7.8 7.72    6.44    4.32    4   4   3.72    3.68    3.68    3.28    5.56    7.36    9.48    10  10.52   11  12.16   11.96   9.44    8.64    7.52    7   6.48    6   5   5.12    6.28    6   5.52    6   6.68    6.08    7.52    8.16    7.72    8.52    8.56    9.2 9.16    8.92    7.44    6   5   3.48    2.92    2.16    2   2   1.2 1   1   1   1.24    1.64    1   1   1.96    2   2   2   1.76    1   1   1   0.52    1.76    3.64    5.12    6   6   6   6   5.52    4.24    2.36    0.88    0   0   0.68    1   1   1   1   1   1   1   0.32    0   0   1   1   1.44    2.44    3.68    5.4 6.88    7   6   6.52    6.76    6.56    5.32    3.6 2.92    3   3.72    3.96    3.8 3   3   3   2.2 2.4 2.28    1.52    1   1   1   1.72    2   1.6 1   1   1   1   1   0.28    0.92    2   2   2.72    3.64    4   4.84    5   4.08    3   3   2.68    2.36    2   1.16    1   1   2   4.92    4.6 4   4   4   4   4.32    4   1.08    1   1.52    2   2   2   1.68    1   1   1.32    1.48    1   1   1.52    2   2   2   1.68    1   1   1.88    1.48    1   1   1   1   1   1   0.12    0.4 1   1   1.2 3.88    4   5   5   4.6 4   4   3.8 2.08    2   1   1   1.44    2.4 3
NR_047520   LOC643837   ,   3   2.2 0.2 0   0   0.28    1   1   1   1   2.2 4.8 5   5.32    5   5   5   5   3.8 1.2 1   0.4 0   0   0   0   0   1   1   1   1   1   1   1   1.56    1   1   1   1   1   1   1   0.44    0.68    1   1.52    3   3.6 4.96    6.8 9   8.32    8.72    8.48    7   7.4 8.8 7.92    7.12    8.84    8.56    9.4 10.2    10  7.24    6.44    6.76    6.16    5.72    4.96    4.8 5.16    6   5.84    4.12    3   3   2.64    2.56    3.08    3   4.16    5   6.72    7   7.16    7.44    5.76    5   4.56    4   3.68    5   5.4 5.52    6   6   5.28    5   3.6 2   2.08    1.48    1   2   2   2   2   2   1.36    1   1   0   0   0.68    1   1   1   1   1   1   1   0.32    0   0   0   1.16    2   2   2   2   2.88    3   3   1.84    1   2   2   2.04    2.12    2   2   2   2   1   1.28    1.96    1.36    2.76    3   3   3   3   2.72    2   1.64    0.76    1   1.36    2   2   2   2   2   1.48    1   0.64    0   0.08    1   1   1.08    2   2   2   2   2.68    2   2   2.16    3.4 4   4   4.2 4.24    4   5.68    6.52    4.6 4   4   3.8 3.8 4   3.12    2.24    2.6 3   4   4   3.2 3   2.2 2   1.4 1.84    1.24    2   2   2   2   2   2   1.16    0.76    0   0   0   0   0   0   0   0.36    1   1.68    2   2   2.92    5.4 6.76    7.64    7   6.88    7   7.36    7.92    6.24    5.92    7.04    9.52    11.52   12.88   14.8    16.36   19.88   22.24   20  19.36   16.92   15.24   13.84   10.88   8.24    5.08    4.96    3.12    3   2.88    2   2.8 2.96    4   4.44    5   6   6   6   5.12    3.28    2   1.56    1   0.08    1.68    2   2   2.84    3   3   3.8 3.92    2.32    2   2.2 2.16    2   2   1.2 1   1   1   0.8 0   0   0   0.72    2.88    3   3   3   3   3   3   2.28    0.12    0   0.52    1   1   1   1   1.44    2   2   1.48    1   1   1   1.56    1.56    1   1   1   1   1   1   0.44    0.8 1.48    3   3   3   3   3   3.56    3.2 2.76    2   2   2   2   2.68    2.44    2   1.76    1   1.4 2   2   1.56    2   2   2   2   2.04    2   2   1.76    1   1   1   1   0.56    0   0   0   0   0   0   0   0   0.72    1.52    2   2   2   2   2   2   1.28    0.48                                                            

注意:map语法很可爱,但如果文件很大,您应该使用 while 循环来提高效率。while 循环避免将整个文件读入内存:

while (<DATA>)
{
    if (/^([\w\s]*?)\s*,\s*(.*)/)
    {
        $line_max{$1} = max split ' ', $2;  
    }
    else
    {
        print "Line $. is bad.\n";  
    }   
}
于 2012-12-19T10:09:26.940 回答