快速比较数据集中的行的方法

时间:2013-11-01 14:41:46

标签: perl

我在R中问了这个问题,得到了很多答案,但是几个小时后他们全部撞坏了我的4Gb Ram计算机,或者他们需要很长时间才能完成。 faster way to compare rows in a data frame

有些人说R不是一件好事。因为我不知道C而且我对Perl有点流利,我会在这里问。

我想知道是否有一种快速方法可以将大数据集的每一行与其他行进行比较,从而识别具有特定同源程度的行。让我们说下面的简单例子,我想要同源性> = 3。

data:
sample_1,10,11,10,13
sample_2,10,11,10,14
sample_3,10,10,8,12
sample_4,10,11,10,13
sample_5,13,13,10,13

输出应该是这样的:

output
   sample    duplicate    matches
1 sample_1   sample_2     3
2 sample_1   sample_4     4
3 sample_2   sample_4     3

2 个答案:

答案 0 :(得分:1)

此解决方案提供了直接比较的替代方案,对于大量数据而言,这将是缓慢的。 基本思想是在读取数据时构建倒排索引。 如果每列有很多不同的值,这会使比较更快。 对于每一行,您查找索引并计算匹配 - 这样您只考虑实际出现此值的样本。 您可能仍然遇到内存问题,因为索引会变得与数据一样大。 为了解决这个问题,您可以缩短样本名称并使用持久索引(例如,使用DB_File)。

use strict;
use warnings;
use 5.010;

my @h;

my $LIMIT_HOMOLOGY = 3;

while(my $line = <>) {
    my @arr = split /,/, $line;

    my $sample_no = shift @arr;
    my %sim;
    foreach my $i (0..$#arr) {
        my $value = $arr[$i];
        our $l;
        *l = \$h[$i]->{$value};
        foreach my $s (@$l) {
           $sim{$s}++;
        }
        push @$l, $sample_no;
    }
    foreach my $s (keys %sim) {
        if ($sim{$s}>=$LIMIT_HOMOLOGY) {
            say "$sample_no: $s. Matches: $sim{$s}";
        }
    }
}

对于25000行,26列,随机整数值介于1和100之间,程序在我的mac书空中花了69秒完成。

答案 1 :(得分:1)

当两条线在相同位置具有相同的数字时计算匹配,

perl -F',' -lane'
  $k = shift @F;
  for my $kk (@o) {
    $m = grep { $h{$kk}[$_] == $F[$_] } 0 .. $#F;
    $m >=3 or next;
    print ++$i, " $kk  $k  $m";
  }
  push @o, $k;
  $h{$k} = [ @F ];
' file

输出,

1 sample_1  sample_2  3
2 sample_1  sample_4  4
3 sample_2  sample_4  3