我正在使用Biopython打开一个大型单入口fasta文件(514兆碱基),因此我可以从特定坐标中提取DNA序列。返回序列的速度相当慢,我只是想知道是否有更快的方法来完成我还没想到的任务。只有一两次点击速度不会是速度问题,但是我正在迭代145,000个坐标列表并且需要几天时间:/
import sys
from Bio import SeqIO
from Bio.Seq import Seq
def get_seq(fasta, cont_start, cont_end, strand):
f = fasta
start_pos = cont_start
end_pos = cont_end
for seq_record in SeqIO.parse(f, "fasta"):
if strand == '-' :
return seq_record.seq[int(start_pos):int(end_pos)].reverse_complement()
elif strand == '+':
return seq_record.seq[int(start_pos):int(end_pos)]
else :
print ' Invalid syntax!
sys.exit(1)
答案 0 :(得分:2)
每次要查找单个链时,您的函数都会解析整个文件。没有必要这样做 - “更好的方法”是解析所有序列一次,并将它们存储到内存中以便以后访问。最简单的方法是将SeqIO.parse
返回的生成器转换为list
或类似的数据结构。
或者,您可以将已解析的SeqRecord
对象存储在数据库中:ZODB
,shelve
或简单使用pickle
即可实现此目的。
但是,根据函数的外观,您始终只返回文件中找到的第一个SeqRecord
的结果(第一次迭代到SeqIO.parse(f, "fasta")
将返回或调用sys.exit(1)
) 。你的意思是yield
而不是(我假设你这样做了吗?)。
以下是我将如何处理它:
# Parse once, store in a list (alternatively, place DB "load" command here
all_seq_records = list(SeqIO.parse(f, "fasta"))
def get_seq(cont_start, cont_end, strand):
assert strand in ["+", "-"], "Invalid strand parameter '%s'" % strand
for seq_record in all_seq_records:
segment = seq_record.seq[int(start_pos):int(end_pos)]
yield segment if strand == "+" else segment.reverse_complement()