Python bitarray反向补码

时间:2015-08-18 12:26:24

标签: python bitarray

我正在使用Python的bitarray module将DNA序列(以二进制文件写入)转换为反向补码。每个核苷酸由以下格式的两位表示:

A - 00, C - 01, G - 10, T - 11

例如,AGCTACGG (00 10 01 11 00 01 10 10)的反向补码为CCGTAGCT (01 01 10 11 00 10 01 11)

这个序列完全占用 16位(2字节),但长度为 9 的序列将采用 18位并填充以占用 24 位( 3 字节)。

目前我使用for循环进行转换,但这个解决方案非常慢。

def reverse_complement( my_bitarray, seq_length ):

    for i in range(0, 2 * seq_length - 1, 2):

        if my_bitarray[i] == my_bitarray[i + 1]:

            if my_bitarray[i] == 0:
                my_bitarray[i], my_bitarray[i + 1] = 1, 1

            else:
                my_bitarray[i], my_bitarray[i + 1] = 0, 0

    #padding if the bitarray is not a multiple of 8 bits in length
    if seq_length / 4 != int():
        my_bitarray.reverse()
        my_bitarray.fill()
        my_bitarray.reverse()

    return my_bitarray

a = bitarray()
a.frombytes(seq[::-1])
b = a[int(seq_start)::] # seq without padding
b.reverse()

reverse_complement(b, seq_length)

有关如何加快此过程的任何提示?

2 个答案:

答案 0 :(得分:1)

如果您不介意从PyPI安装boltons软件包,可以执行以下操作:

from itertools import chain

from bitarray import bitarray
from boltons.iterutils import pairwise

original = bitarray('0010011100011010')
complement = ~original
reverse_complement = bitarray(chain.from_iterable(reversed(pairwise(complement))))
assert reverse_complement == bitarray('0101101100100111')

更新

boltons v16.2.0起,pairwise执行其他操作,因此应将答案更改为使用chunked

from boltons.iterutils import chunked
reverse_complement = bitarray(chain.from_iterable(reversed(chunked(complement, 2))))

答案 1 :(得分:1)

您提供的代码并未给出您指出的答案。

这是给出正确答案的代码。也许它也足够快:

def reverse_complement(my_bitarray):
    # First reverse by twos
    my_bitarray = zip(my_bitarray[0::2], my_bitarray[1::2])
    my_bitarray = reversed(list(my_bitarray))
    my_bitarray = (i for t in my_bitarray for i in t)
    my_bitarray = bitarray(my_bitarray)

    # Then complement
    my_bitarray.invert()
    return my_bitarray

请注意,您不必担心填充。 bitarray.bitarray()为您管理所有这些。