2013-08-27 3 views
1

Я хочу сравнить несколько файлов (15-20), которые являются gzipped, и восстанавливать из них строки, которые являются общими. Но это не так просто. Строки, которые являются точными в определенных столбцах, а также я хотел бы иметь для них подсчет информации о том, сколько файлов они присутствовали. Если 1, строка уникальна для файла и т. Д. Было бы неплохо также сохранить эти имена файлов.Сравнение нескольких файлов

каждый файл выглядит ул так:

##SAMPLE=<ID=NormalID,Description="Cancer-paired normal sample. Sample ID 'NORMAL'"> 
##SAMPLE=<ID=CancerID,Description="Cancer sample. Sample ID 'TUMOR'"> 
#CHROM POS  ID  REF  ALT  QUAL FILTER INFO FORMAT NormalID_NORMAL CancerID_TUMOR 
chrX 136109567  .  C  CT  .  PASS IC=8;IHP=8;NT=ref;QSI=35;QSI_NT=35;RC=7;RU=T;SGT=ref->het;SOMATIC;TQSI=1;TQSI_NT=1;phastCons;CSQ=T|ENSG00000165370|ENST00000298110|Transcript|5KB_downstream_variant|||||||||YES|GPR101|||||  DP:DP2:TAR:TIR:TOR:DP50:FDP50:SUBDP50 23:23:21,21:0,0:2,2:21.59:0.33:0.00 33:33:16,16:13,13:4,4:33.38:0.90:0.00 
chrX 150462334  .  T  TA  .  PASS IC=2;IHP=2;NT=ref;QSI=56;QSI_NT=56;RC=1;RU=A;SGT=ref->het;SOMATIC;TQSI=2;TQSI_NT=2;CSQ=A||||intergenic_variant||||||||||||||| DP:DP2:TAR:TIR:TOR:DP50:FDP50:SUBDP50 30:30:30,30:0,0:0,0:31.99:0.00:0.00  37:37:15,17:16,16:6,5:36.7:0.31:0.00 

Файлы табуляцией. Если строка начинается с #, игнорируйте эту строку. Нас интересуют только те, кто этого не делает. Принимая координаты python, основанные на 0, нас интересуют 0,1,2,3,4 поля. Они должны сопоставлять файлы, которые будут сообщаться как общие. Однако мы все еще нуждаемся tohold информации о остальной coulmns/полей, так что они могут быть записаны карапузом он выходной файл

Сейчас у меня есть следующий код:

import gzip 
filenames = ['a','b','c'] 
files = [gzip.open(name) for name in filenames] 

sets = [set(line.strip() for line in file if not line.startswith('#')) for file in files] 
common = set.intersection(*sets) 
for file in files: file.close() 
print common 

В моей currenyt коде я делаю не знаете, как правильно реализовать if, если не line.startswith() (в каком месте?), и как указать столбцы в строке, которые должны быть сопоставлены. Не говоря уже о том, что я понятия не имею, как получить строки, которые представлены, например, в 6 файлах, или присутствовать в 10 из 15 файлов. Любая помощь?

ответ

1

собирать строки в словаре с полями, которые делают их похожими, как ключ:

from collections import defaultdict 
d = defaultdict(list) 

def process(filename, line): 
    if line[0] == '#': 
     return 

    fields = line.split('\t') 
    key = tuple(fields[0:5]) # Fields that makes lines similar/same 
    d[key].append((filename, line)) 

for filename in filenames: 
    with gzip.open(filename) as fh: 
     for line in fh: 
      process(filename, line.strip()) 

Теперь у вас есть словарь со списками имен файлов строки кортежей. Теперь вы можете печатать все строки, которые появляются более чем в 10 раз:

for l in d.values(): 
    if len(l) < 10: continue 

    print 'Same key found %d times:' % len(l) 

    for filename, line in l: 
     print '%s: %s' % (filename, line) 
+0

У меня следующая проблема: TypeError: unhashable типа: «список» в строках: d [ключ] .append и процесс (имя файла [.. .] – Irek

+0

Ах, да. Try 'key = tuple (поля [0: 5])' –

+0

Это отличный ответ, и концепция была понята с самого начала. Я буду играть вокруг себя с хорошим выходом (кстати, текущий один уже очень хорош и позволяет очень легко фильтровать). Большое спасибо – Irek

Смежные вопросы