反复访问LARGE fasta文件。大多数内存有效的方法

时间:2013-06-10 04:39:37

标签: python performance biopython fasta dna-sequence

我正在使用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)

1 个答案:

答案 0 :(得分:2)

每次要查找单个链时,您的函数都会解析整个文件。没有必要这样做 - “更好的方法”是解析所有序列一次,并将它们存储到内存中以便以后访问。最简单的方法是将SeqIO.parse返回的生成器转换为list或类似的数据结构。

或者,您可以将已解析的SeqRecord对象存储在数据库中:ZODBshelve或简单使用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()