Я программировал в течение нескольких месяцев, поэтому я не эксперт. У меня есть два огромных текстовых файла (omni, ~ 20 GB, ~ 2.5M строк, dbSNP, ~ 10 GB, ~ 60M строк). У них есть первые несколько строк, не обязательно с разделителями табуляции, начиная с «#» (заголовок), а остальные строки организованы в столбцах с разделителями табуляции (фактические данные).Получите данные из огромного текстового файла, чтобы эффективно заменить данные в другом огромном текстовом файле (Python)
Первые две колонки каждой строки содержат номер хромосомы и положение на хромосоме, а третий столбец содержит идентификационный код. В «omni» файле у меня нет идентификатора, поэтому мне нужно найти позицию в файле dbSNP (база данных) и создать копию первого файла, заполненного идентификаторами.
Из-за ограничений памяти я решил прочитать два файла по очереди и перезапустить их из последней строки. Меня не удовлетворяет эффективность моего кода, потому что я чувствую, что он медленнее, чем может быть. Я почти уверен, что это моя вина из-за отсутствия опыта. Есть ли способ сделать это быстрее с помощью Python? Может возникнуть проблема с открытием и закрытием файлов?
Я обычно запустить скрипт в GNOME Terminal (Python 2.7.6, Ubuntu 14,04), как это:
питон -u Replace_ID.py> Replace.log 2> Replace.err
Спасибо вам большое заблаговременно.
всенаправленный (Omni example):
...
#CHROM POS ID REF ALT ...
1 534247. КТ ...
...
dbSNP (dbSNP example):
...
#CHROM POS-ID Ref ALT ...
1 10019 rs376643643 ТА Т ...
...
выход должен быть точно таким же, как Omni файла, но с Rs ID после positi на.
Код:
SNPline = 0 #line in dbSNP file
SNPline2 = 0 #temporary copy
omniline = 0 #line in omni file
line_offset = [] #beginnings of every line in dbSNP file (stackoverflow.com/a/620492)
offset = 0
with open("dbSNP_build_141.vcf") as dbSNP: #database
for line in dbSNP:
line_offset.append(offset)
offset += len(line)
dbSNP.seek(0)
with open("Omni_replaced.vcf", "w") as outfile:
outfile.write("")
with open("Omni25_genotypes_2141_samples.b37.v2.vcf") as omni:
for line in omni:
omniline += 1
print str(omniline) #log
if line[0] == "#": #if line is header
with open("Omni_replaced.vcf", "a") as outfile:
outfile.write(line) #write as it is
else:
split_omni = line.split('\t') #tab-delimited columns
with open("dbSNP_build_141.vcf") as dbSNP:
SNPline2 = SNPline #restart from last line found
dbSNP.seek(line_offset[SNPline])
for line in dbSNP:
SNPline2 = SNPline2 + 1
split_dbSNP = line.split('\t')
if line[0] == "#":
print str(omniline) + "#" + str(SNPline2) #keep track of what's happening.
rs_found = 0 #it does not contain the rs ID
else:
if split_omni[0] + split_omni[1] == split_dbSNP[0] + split_dbSNP[1]: #if chromosome and position match
print str(omniline) + "." + str(SNPline2) #log
SNPline = SNPline2 - 1
with open("Omni_replaced.vcf", "a") as outfile:
split_omni[2] = split_dbSNP[2] #replace the ID
outfile.write("\t".join(split_omni))
rs_found = 1 #ID found
break
else:
rs_found = 0 #ID not found
if rs_found == 0: #if ID was not found in dbSNP, then:
with open("Omni_replaced.vcf", "a") as outfile:
outfile.write("\t".join(split_omni)) #keep the line unedited
else: #if ID was found:
pass #no need to do anything, line already written
print "End."
Не могли бы вы предоставить дополнительную информацию для проведения тестирования? Например, укажите 5 строк для каждого файла и 5 строк, которые показывают, что процесс замены завершен? Вероятно, это позволит лучше понять предоставленный вами код, а также позволит протестировать некоторые изменения и проверить согласованность. –
@ ArthurVaïsse Спасибо за ваше предложение. Я редактировал исходное сообщение. Я мог бы добавить только две ссылки, поэтому вот пример выходного файла: lucabetti.altervista.org/file/Output_example.vcf – 4Kinesis