Я делаю сценарий парсера .fasta. (Я знаю, что для файлов .fasta уже существуют парсеры, но мне нужна практика работы с большими файлами, и я подумал, что это хорошее начало).
Цель программы: взять очень большой .fasta
файл с несколькими последовательностями и вернуть обратное дополнение каждой последовательности в новом файле.
У меня есть сценарий, который читает его по одной строке за раз, но каждая строка занимает всего около 50 байт в обычном файле .fasta. Таким образом, в буферизации только одной строки за раз нет необходимости. Есть ли способ установить количество строк для буферизации за раз?
Для людей, которые не знают, что такое fasta: .fasta
файл - это текстовый файл с последовательностями ДНК, каждая из которых имеет строку заголовка перед последовательностью ДНК / РНК / белка, отмеченной знаком «› ». Пример:
>Sequence_1
ATG
TATA
>Sequence_2
TATA
GACT
ATG
Обзор моего кода:
Прочтите первый байт каждой строки, чтобы сопоставить расположение последовательностей в файле, найдя символы «› ».
Используйте эту карту, чтобы читать каждую последовательность в обратном порядке построчно (это то, что я хочу изменить, чтобы иметь возможность)
- Обеспечить регресс
- дополнять пары оснований в строке (I.E. G- ›C)
- Запишите эту строку в новый файл
Вот каким должен быть весь соответствующий код, чтобы вы могли видеть функции, которые вызывают строки, которые я пытаюсь изменить: (возможно, можно пропустить)
def get_fasta_seqs(BIGFILE): #Returns returns an object containing all of seq locations
f = open(BIGFILE)
cnt = 0
seq_name = []
seq_start = []
seq_end = []
seqcount = 0
#print(line)
#for loop skips first line check for seq name
if f.readline(1) == '>':
seq_name.append(cnt)
seq_start.append(cnt+1)
seqcount =+ 1
for line in f:
cnt += 1
if f.readline(1) == '>':
seq_name.append(cnt)
seq_start.append(cnt+1)
seqcount += 1
if seqcount > 1:
seq_end.append(cnt-1)
seq_end.append(cnt-1) #add location of final line
seqs = fileseq(seq_name,seq_start,seq_end,seqcount) #This class only has a __init__ function for these lists
return seqs
def fasta_rev_compliment(fasta_read,fasta_write = "default",NTtype = "DNA"):
if fasta_write == 'default':
fasta_write = fasta_read[:-6] + "_RC.fasta"
seq_map = get_fasta_seqs(fasta_read)
print(seq_map.seq_name)
f = open(fasta_write,'a')
for i in range(seq_map.seqcount): #THIS IS WHAT I WANT TO CHANGE
line = getline(fasta_read,seq_map.seq_name[i]+1) #getline is reading it as 1 indexed?
f.write(line)
my_fasta_seqs = get_fasta_seqs(fasta_read)
for seqline in reversed(range(seq_map.seq_start[i],seq_map.seq_end[i]+1)):
seq = getline(fasta_read,seqline+1)
seq = seq.replace('\n','')
seq = reverse_compliment(seq,NTtype = NTtype) #this function just returns the reverse compliment for that line.
seq = seq + '\n'
f.write(seq)
f.close()
fasta_rev_compliment('BIGFILE.fasta')
Основной фрагмент кода, который я хочу изменить, находится здесь:
for i in range(seq_map.seqcount): #THIS IS WHAT I WANT TO CHANGE
line = getline(fasta_read,seq_map.seq_name[i]+1) #getline is reading it as 1 indexed?
f.write(line)
my_fasta_seqs = get_fasta_seqs(fasta_read)
for seqline in reversed(range(seq_map.seq_start[i],seq_map.seq_end[i]+1)):
seq = getline(fasta_read,seqline+1)
Я хочу что-то вроде этого:
def fasta_rev_compliment(fasta_read,fasta_write = "default",NTtype = "DNA",lines_to_record_before_flushing = 5):
###MORE CODE###
#i want something like this
for i in range(seq_map.seqcount): #THIS IS WHAT I WANT TO CHANGE
#is their a way to load
line = getline(fasta_read,seq_map.seq_name[i]+1) #getline is reading it as 1 indexed?
f.write(line)
my_fasta_seqs = get_fasta_seqs(fasta_read)
for seqline in reversed(range(seq_map.seq_start[i],seq_map.seq_end[i]+1)):
seq = getline(fasta_read,seqline+1)
#Repeat n = 5 (or other specified number) times until flushing ram.
Проблема, с которой я столкнулся, заключается в том, что мне нужно прочитать файл в обратном порядке. Все методы, которые я могу найти, не работают, когда вы пытаетесь применить их для чтения файла в обратном направлении. Есть ли что-то, что может читать файл по частям, но в обратном порядке?
Или: что-нибудь еще, что может сделать это более эффективным при настройке с низким объемом памяти. Сейчас он почти не использует память, но занимает 21 секунду для файла размером 100 КБ, содержащего около 12 000 строк, но обрабатывает файл мгновенно, используя метод file.readlines()
.