#python #bash #optimization #awk
#python #bash #оптимизация #awk
Вопрос:
Я пытаюсь преобразовать файл 1 (файл gtf, если какой-либо биоинформатик проходит мимо) со строками типа:
1 X exon 1 300000 1000 - . gene_id "Z.633"; transcript_id "Z.633.mrna1"; exon_number "1";
1 X transcript 1 300000 1000 - . gene_id "Z.633"; transcript_id "Z.633.mrna1";
1 X exon 300005 300500 1000 - . gene_id "Y.6330"; transcript_id "Y.6330.mrna1"; exon_number "2";
1 X exon 300500 310000 1000 . gene_id "Y.6330"; transcript_id "Y.6330.mrna1"; exon_number "1";
1 X transcript 30005 310000 1000 . gene_id "Y.6330"; transcript_id "Y.6330.mrna1";
в файл, в котором все «Z» будут заменены на «F», и другие соответствия. Все соответствия находятся в файле 2, который я использую в качестве словаря, столбец 1 — это ключи, столбец 2 — значения.
пример файла 2:
Z.633 F.633
Y.6330 U.6330
пример результата :
1 X exon 1 300000 1000 - . gene_id "F.633"; transcript_id "F.633.mrna1"; exon_number "1";
1 X transcript 1 300000 1000 - . gene_id "F.633"; transcript_id "F.633.mrna1";
1 X exon 300005 300500 1000 - . gene_id "U.6330"; transcript_id "U.6330.mrna1"; exon_number "2";
1 X exon 300500 310000 1000 . gene_id "U.6330"; transcript_id "U.6330.mrna1"; exon_number "1";
1 X transcript 30005 310000 1000 . gene_id "U.6330"; transcript_id "U.6330.mrna1";
файл 1 содержит около 200000 строк, а файл 2 — 20000.
Для этого я использовал awk-скрипт:
NR == FNR {
rep[ $2 ] = $1
next
}
{
for (key in rep)
gsub(key, rep[key])
print
}
и затем:
awk -f dict.awk file2 file1 > newfile
Моя проблема в том, что скрипт фактически выполняется в течение нескольких дней… Есть ли какой-либо способ, которым я мог бы это улучшить?
Есть ли более подходящий язык программирования для этой проблемы? (Я пробовал python, но время выполнения было еще хуже)
(использовался скрипт на python:)
def replaceWithDictionnary(dictFileName,fileToReplaceName,newFileName):
import re
with open(dictFileName,'r') as d:
dictFile = dict((line.strip().split())[::-1] for line in d)
with open(newFileName,'w') as g:
with open(fileToReplaceName,'r') as f:
for line in f.readlines():
for d_key, d_value in dictFile.items():
if bool(re.search(d_key "D ", line)):
#if """ d_key """ in line:
#print(d_key)
newline=line.replace(d_key,d_value)
#print(d_value)
g.write(newline)
continue
Я могу сказать, что это не та часть словаря, которая занимает так много времени, потому что я тестировал ее с меньшим файлом1, и она выполнялась быстро…
Ответ №1:
Предполагая, что для каждой записи требуется заменить только одну gene_id
функцию, которую всегда можно найти в 10-м столбце, как в вашем примере файла, вы можете найти ее и вызвать gsub
один раз, вместо вызова 20 тысяч функций для каждой записи.
> cat tst.awk
NR==FNR {
r[$1] = $2
next
}
{
x = $10
gsub(/"|;/, "", x)
gsub(x, r[x])
print
}
awk -f tst.awk file2 file1