我有一个大型数据集,如下所示:
identifier,feature 1, feature 2, feature 3, ...
29239999, 2,5,3,...
29239999, 2,4,3,...
29239999, 2,6,7,...
17221882, 2,6,7,...
17221882, 1,1,7,...
我想编写一个脚本,按标识符对这些行进行分组(因此前3个和后2个将被分组)以便进行比较。因此,举例来说,我会得到3 29239999,并将两个中的一个作为3,将3中的特征作为3,最后将特征3作为7.特别是,我想采用具有最大特征2的那个(它会是29239999的第三行。
我的具体问题:我的两个选项:(1)哈希和(2)使每个标识符成为一个对象,然后比较它们,这是最好的?
答案 0 :(得分:1)
如果你真的在使用“大型”数据集并且数据已经按照你的例子中的id分组,那么我建议你在去处理这些数据而不是构建一个巨大的哈希值。
use strict;
use warnings;
# Skip Header row
<DATA>;
my @group;
my $lastid = '';
while (<DATA>) {
my ($id, $data) = split /,\s*/, $_, 2;
if ($id ne $lastid) {
processData($lastid, @group);
@group = ();
}
push @group, $data;
$lastid = $id;
}
processData($lastid, @group);
sub processData {
my $id = shift;
return if ! @_;
print "$id " . scalar(@_) . "\n";
# Rest of code here
}
__DATA__
identifier,feature 1, feature 2, feature 3, ...
29239999, 2,5,3,...
29239999, 2,4,3,...
29239999, 2,6,7,...
17221882, 2,6,7,...
17221882, 1,1,7,...
输出
29239999 3
17221882 2
答案 1 :(得分:1)
听起来你只想打印任何一对ID和Feature 3的第一次出现。是吗?
这个程序会为你做到这一点。它期望输入文件的路径作为命令行上的参数,并将修改后的数据发送到STDOUT。
use strict;
use warnings;
my %seen;
print scalar <>; # Copy header line
while (<>) {
next unless /\S/;
my @fields = split /,/, $_, 5;
my $key = join '/', @fields[0,3];
print unless $seen{$key}++;
}
<强>输出强>
identifier,feature 1, feature 2, feature 3, ...
29239999, 2,5,3,...
29239999, 2,6,7,...
17221882, 2,6,7,...