2012-08-08 34 views
4

我有類似下面的一個表,並想以計算本因素的不同組合。例如所有時間的數量(1表示存在,0表示不存在)。第一次缺席的時間是休息時間,第二時間缺席的次數是其他時間的休息時間,還有一些缺席休息時間的休息時間。計算爲存在或不存在因子的組合在表中

在殼是很簡單的檢查時間的數目都是本

AWK「{如果(($ 2 == 1)& &($ 90元== 1)& &($ 4 == 1) & &($ ==您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最後爲不存在,但其他都存在
4的第三和第四不存在但其它的本
5前三缺席但其他都存在。

在表這樣其具有與n行的數目的列的固定數量的,如何可以計算存在和不存在這些的組合?

請幫忙。

謝謝

+0

你能證明你已經嘗試過的代碼?所以答案可以更好地適應,並嘗試幫助你? – 2012-08-08 11:54:30

+0

這不僅僅是按所有列分組的選擇計數(*)嗎? – frankc 2012-08-08 15:05:02

回答

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 

我敢肯定,這可以改善。

+0

這不包括每個組合存在的時間。 – 2012-08-08 12:09:47

+1

現在,我希望... – hochl 2012-08-08 12:18:55

+0

輝煌:)謝謝 – Angelo 2012-08-08 12:27:14

2

比報知的解決方案長,但它是如何工作的,可能更清楚:

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 

我不會做所有的情況,但是這應該給你的想法。

+0

謝謝,是的,這是明確的:) – Angelo 2012-08-08 12:27:53

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 
相關問題