计算表中是否存在因子的组合

时间:2012-08-08 11:42:45

标签: python perl bash bioinformatics

我有一个如下表所示的表格,并希望计算出现有因素的不同组合。例如,所有存在的时间数(1表示存在,0表示不存在)。首先缺席但没有休息的时间,没有时间秒的数量,但是其他的存在,并且还缺少双打和三元组以及休息时间。

在shell中,检查所有存在的时间非常简单

awk'{if(($ 2 == 1)&&($ 3 == 1)&&($ 4 == 1)&&($ 5 == 1)&&($ 6 == 1))打印$ 1}'ALL_Freq_motif_AE_Uper

但问题在于计算所有可能的组合。

表格如下:

CEBP    HEB     TAL1    RUNX1   SPI1
1       1       1       1       1
0       1       1       1       1
1       1       0       0       1
1       1       1       1       0
0       0       0       1       1

现在这个表格出现了不同的组合

1组合,其中全部存在。
2首先缺席,所有其他人都在场 3最后缺席但其他人在场 第四和第四个缺席,但其他人在场 5前三个缺席,但其他人在场。

在这样一个具有固定列数和n行数的表格中,如何计算这些存在与否的组合?

请帮助。

谢谢

3 个答案:

答案 0 :(得分:4)

假设data包含您的数据,这可以完成这项工作:

with open("data") as f:
        lines=[line.strip().split() for line in f]
combinations={}
for combination in lines[1:]:
        key=", ".join([lines[0][i]
                for i in xrange(len(combination))
                if combination[i] != '0'])
        combinations[key]=combinations.setdefault(key, 0)+1
for key, value in combinations.iteritems():
        print value, '\t', key

或使用馆藏模块:

import collections

with open("data") as f:
        lines=[line.strip().split() for line in f]

combinations=collections.Counter(
        ", ".join(lines[0][i]
                for i in xrange(len(combination))
                        if combination[i] != '0')
                for combination in lines[1:])

for key, value in combinations.iteritems():
        print value, '\t', key

编辑:使用生成器表达式保存资源的另一个版本

import collections

with open("data") as f:
        lines=(line.strip().split() for line in f)
        header=next(lines)
        combinations=collections.Counter(
                ", ".join(header[i]
                        for i in xrange(len(combination))
                                if combination[i] != '0')
                        for combination in lines)
        for key, value in combinations.iteritems():
                print value, '\t', key

我确信这可以改进。

答案 1 :(得分:3)

一个Perl程序,它将所有组合计算为二进制数。我重复几行以确保计数有效。

use strict;
use warnings;
use Bit::Vector;

# CEBP       HEB     TAL1      RUNX1   SPI1
my @factors = (
    [1,      1,       1,       1,       1],
    [1,      1,       1,       1,       1],
    [1,      1,       1,       1,       1],
    [0,      1,       1,       1,       1],
    [1,      1,       0,       0,       1],
    [1,      1,       1,       1,       0],
    [0,      0,       0,       1,       1],
    [0,      0,       0,       1,       1],
    [0,      0,       0,       1,       1],
);

my %combo;

for my $row (@factors) {
    my $v = Bit::Vector->new_Bin(32, join('', @$row))->to_Dec;
    $combo{$v}++;
}

for my $v (sort keys %combo) {
    printf "Result: %3d  %5s Count: %d\n", 
        $v, 
        Bit::Vector->new_Dec(5, $v)->to_Bin,
        $combo{$v}
    ;
}

输出:

Result:  15  01111 Count: 1
Result:  25  11001 Count: 1
Result:   3  00011 Count: 3
Result:  30  11110 Count: 1
Result:  31  11111 Count: 3

答案 2 :(得分:2)

比hochi的解决方案更长,但它可能更清晰:

with open("data") as f:
    next(f)    # Skip header row
    lines=[[int(n) for n in x.strip().split()] for x in f if x.strip()]


count = 0
for row in lines:
    if all(row):
        count += 1
print "All present:", count

count = 0
for row in lines:
    if (not row[0]) and all(row[1:]):
        count += 1
print "All except first column are 1:", count

我不会做所有的情况,但这应该给你一个想法。