4

以下のような表があり、存在する要因のさまざまな組み合わせを計算したいと思います。たとえば、すべてが存在する回数(1は存在を示し、0は不在を示します)。最初の時間は存在しないが残りは存在し、2番目の時間は存在しないが他の時間は存在し、ダブルとトリプルの場合は存在せず、残りが存在します。

シェルでは、すべてが存在する回数を確認するのは非常に簡単です

awk'{if(($ 2 == 1)&&($ 3 == 1)&&($ 4 == 1)&&($ 5 == 1)&&($ 6 == 1))print $ 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 3番目と4番目は存在しませんが、他は存在します
5最初の3つは存在しませんが、他は存在します。

列数と行数が固定されているこのようなテーブルで、これらの存在と不在の組み合わせを計算するにはどうすればよいですか?

親切に助けてください。

ありがとうございました

4

3 に答える 3

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

これは改善できると確信しています。

于 2012-08-08T12:08:07.977 に答える
3

すべての組み合わせを2進数のようにカウントする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
于 2012-08-08T12:47:04.077 に答える
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

私はすべての場合を行うわけではありませんが、これはあなたにアイデアを与えるはずです。

于 2012-08-08T12:21:58.777 に答える