如何使用biopython将multi-fasta文件拆分为相同序列长度的块并更改头

如何使用biopython将multi-fasta文件拆分为相同序列长度的块并更改头,python,bioinformatics,biopython,fasta,Python,Bioinformatics,Biopython,Fasta,首先,我为自己的无知道歉。我需要将我的多序列fasta文件分解为大小相等的块,以用于管道下游。我从来没有遇到过任何可以轻松实现这一点或以我正在寻找的格式实现这一点的东西 文件输入示例: 原件.fas >contig1 ACGTA >contig2 GGGATAGTCA >contig3 GACTATTTT 上面的例子fasta有25bp。如果我将“chunk number”参数设置为“4”,那么我希望我的输出文件都有7个碱基对,除了最后一个文件有剩余的4bp。它看起来是这样的: 1.fas >续

首先,我为自己的无知道歉。我需要将我的多序列fasta文件分解为大小相等的块,以用于管道下游。我从来没有遇到过任何可以轻松实现这一点或以我正在寻找的格式实现这一点的东西

文件输入示例:

原件.fas >contig1 ACGTA

>contig2 GGGATAGTCA

>contig3 GACTATTTT

上面的例子fasta有25bp。如果我将“chunk number”参数设置为“4”,那么我希望我的输出文件都有7个碱基对,除了最后一个文件有剩余的4bp。它看起来是这样的:

1.fas >续表1:0-4 ACGTA

>contig2:0-1 GG

chunk2.fas >续2:2-7 GATAGTC

3.fas >续2:9-9 A

>续3:0-5 GACTAC

chunk4.fas >续3:6-9 TTTT

请注意,每个生成的chunk*.fas包括7个碱基对,chunk4.fas中的剩余碱基对除外。此外,区块文件中的每个结果序列头都与原始序列头不同,因此它们包括“:”以及从原始序列派生的“开始”和“停止”位置

biopython cookbook有一个非常好的批量迭代器工具,我想我的答案就在操作这段代码中,但我不知道该怎么做

感谢您的帮助。干杯


def batch_iterator(iterator, batch_size):
    """Returns lists of length batch_size.
    This can be used on any iterator, for example to batch up
    SeqRecord objects from Bio.SeqIO.parse(...), or to batch
    Alignment objects from Bio.AlignIO.parse(...), or simply
    lines from a file handle.
    This is a generator function, and it returns lists of the
    entries from the supplied iterator.  Each list will have
    batch_size entries, although the final list may be shorter.
    """
    entry = True  # Make sure we loop once
    while entry:
        batch = []
        while len(batch) < batch_size:
            try:
                entry = next(iterator)
            except StopIteration:
                entry = False
            if not entry:
                # End of file
                break
            batch.append(entry)
        if batch:
            yield batch

record_iter = SeqIO.parse('aVan.fa', 'fasta')

for i, batch in enumerate(batch_iterator(record_iter, 1000), start=1):
    filename = 'group_{}.fasta'.format(i)
    count = SeqIO.write(batch, filename, 'fasta')
    print('Wrote {} records to {}'.format(count, filename))

def批处理迭代器(迭代器,批处理大小):
“”“返回批次大小的长度列表。
这可以在任何迭代器上使用,例如用于批处理
SeqRecord对象来自Bio.SeqIO.parse(…),或批处理
来自Bio.AlignIO.parse(…)的对齐对象,或者
文件句柄中的行。
这是一个生成器函数,它返回
来自提供的迭代器的项。每个列表都有
批量大小条目,尽管最终列表可能较短。
"""
entry=True#确保循环一次
进入时:
批次=[]
而透镜(批次)<批次尺寸:
尝试:
entry=next(迭代器)
除停止迭代外:
输入=假
如果没有输入:
#文件结束
打破
批处理追加(条目)
如果是批次:
产量批次
记录=SeqIO.parse('aVan.fa','fasta')
对于i,枚举中的批(批迭代器(记录iter,1000),开始=1):
文件名='group_{}.fasta'。格式(i)
count=SeqIO.write(批处理,文件名'fasta')
打印('将{}条记录写入{}'。格式(计数,文件名))

这不是一项容易的任务,但请看一下此实现:

from Bio import SeqIO
from Bio.SeqRecord import SeqRecord

chunk_number = 4
records = list(SeqIO.parse("input.fasta", "fasta"))
chunk_size = sum(len(r) for r in records) // chunk_number + 1


def create_batch(records, chunk_size):
    record_it = iter(records)

    record = next(record_it)
    current_base = 0

    batch = []
    batch_size = 0

    # While there are new records, keep creating new batches.
    while record:
        # Loop over records untill the batch is full. (or no new records)
        while batch_size != chunk_size and record:

            end = current_base + chunk_size - batch_size
            seq = record[current_base:end]

            end_of_slice = current_base + len(seq) - 1
            fasta_header = record.id + ":{}-{}".format(current_base, end_of_slice)

            seq.id = seq.name = fasta_header
            seq.description = ''
            batch.append(seq)

            current_base += len(seq)
            batch_size += len(seq)

            # Current record is exhausted, get a new one.
            if current_base >= len(record):
                record = next(record_it, None)
                current_base = 0

        # We have a batch with the correct size (or no new bathces)
        yield batch
        batch = []
        batch_size = 0


for i, batch in enumerate(create_batch(records, chunk_size)):
    filename = "chunk{}.fasta".format(i)
    SeqIO.write(batch, filename, "fasta")
网上有很好的工具
现在:)

这是难以置信的强大。非常感谢!你在这个项目上为我节省了很多时间!