【问题标题】:Repeatedly Accessing LARGE fasta files. Most mem efficifent method?反复访问 LARGE fasta 文件。最节省内存的方法?
【发布时间】:2013-06-10 04:39:37
【问题描述】:

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

【问题讨论】:

  • 您的意思是在这些坐标处为 FASTA 文件中的 所有 记录生成一个序列吗?如果是这样,您可能想使用yield - 这将只返回第一个seq_record 的序列部分。
  • @JoachimIsaksson:不,这是正确的语法。第二个参数是string identifying the input format(这里也是f=fasta,这样只会导致相同的值被传递两次)。
  • @davidcain 啊,哎呀,这显然是早上喝咖啡前阅读代码的效果:)

标签: python performance biopython fasta dna-sequence


【解决方案1】:

您的函数在每次要查找单链时解析整个文件。没有必要这样做——“更好的方法”是一次性解析所有序列,并将它们存储到内存中以供以后访问。最简单的方法是将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()

【讨论】:

  • 感谢您的 cmets 和建议的代码 David!我只解析一个 fasta 文件,并且从解析 gff 注释文件中提取坐标指定的序列。所以我调用 get_seq 来获取开始和结束位置的序列。我会玩弄你的建议。那里肯定有一些新的东西让我思考:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-21
  • 2020-05-02
  • 2015-08-06
  • 1970-01-01
  • 2010-10-22
  • 2013-10-30
相关资源
最近更新 更多