比较文件内部字母序列的最佳方法?

时间:2010-09-09 11:00:32

标签: python

我有一个文件,有很多字母序列 其中一些序列可能是相同的,所以我想比较它们,所有这些 我正在做这样的事情,但这并不是我想要的:

for line in fl:
line = line.split()
for elem in line:
    if '>' in elem:
        pass
    else:
        for el in line:
            if elem == el:
                print elem, el

文件示例:

>1
GTCGTCGAAGCATGCCGGGCCCGCTTCGTGTTCGCTGATA  
>2
GTCGTCGAAAGAGGTCT-GACCGCTTCGCGCCCGCTGGTA    
>3
GTCGTCGAAAGAGGCTT-GCCCGCCACGCGCCCGCTGATA  
>4
GTCGTCGAAAGAGGCTT-GCCCGCTACGCGCCCCCTGATA  
>5
GTCGTCGAAAGAGGTCT-GACCGCTTCGCGCCCGCTGGTA  
>6
GTCGTCGAAAGAGTCTGACCGCTTCTCGCCCGCTGATACG  
>7
GTCGTCGAAAGAGGTCT-GACCGCTTCTCGCCCGCTGATA

所以我想要知道是否有任何序列完全等于1,或者等于2,等等。

4 个答案:

答案 0 :(得分:8)

如果目标只是将类似的序列组合在一起,那么简单地对数据进行排序就可以了。这是一个解决方案,它使用BioPython来解析输入的FASTA文件,对序列集合进行排序,使用标准的Python itertools.groupby函数来合并相同序列的id,并输出一个新的FASTA文件:

from itertools import groupby
from Bio       import SeqIO

records = list(SeqIO.parse(file('spoo.fa'),'fasta'))

def seq_getter(s): return str(s.seq)
records.sort(key=seq_getter)

for seq,equal in groupby(records, seq_getter):
  ids = ','.join(s.id for s in equal)
  print '>%s' % ids
  print seq

输出:

>3
GTCGTCGAAAGAGGCTT-GCCCGCCACGCGCCCGCTGATA
>4
GTCGTCGAAAGAGGCTT-GCCCGCTACGCGCCCCCTGATA
>2,5
GTCGTCGAAAGAGGTCT-GACCGCTTCGCGCCCGCTGGTA
>7
GTCGTCGAAAGAGGTCT-GACCGCTTCTCGCCCGCTGATA
>6
GTCGTCGAAAGAGTCTGACCGCTTCTCGCCCGCTGATACG
>1
GTCGTCGAAGCATGCCGGGCCCGCTTCGTGTTCGCTGATA

答案 1 :(得分:2)

以下脚本将返回序列计数。它返回一个字典,其中包含各个不同的序列作为键以及这些序列出现的数字(每行的第一部分)。

#!/usr/bin/python
import sys
from collections import defaultdict

def count_sequences(filename):
    result = defaultdict(list)
    with open(filename) as f:
        for index, line in enumerate(f):        
            sequence = line.replace('\n', '')
            line_number = index + 1
            result[sequence].append(line_number)
    return result

if __name__ == '__main__':
    filename = sys.argv[1]
    for sequence, occurrences in count_sequences(filename).iteritems():
        print "%s: %s, found in %s" % (sequence, len(occurrences), occurrences)

示例输出:

etc@etc:~$ python ./fasta.py /path/to/my/file
GTCGTCGAAAGAGGCTT-GCCCGCTACGCGCCCCCTGATA: 1, found in ['4']
GTCGTCGAAAGAGGCTT-GCCCGCCACGCGCCCGCTGATA: 1, found in ['3']
GTCGTCGAAAGAGGTCT-GACCGCTTCGCGCCCGCTGGTA: 2, found in ['2', '5']
GTCGTCGAAAGAGGTCT-GACCGCTTCTCGCCCGCTGATA: 1, found in ['7']
GTCGTCGAAGCATGCCGGGCCCGCTTCGTGTTCGCTGATA: 1, found in ['1']
GTCGTCGAAAGAGTCTGACCGCTTCTCGCCCGCTGATACG: 1, found in ['6']

<强>更新

更改了代码以使用dafaultdictfor循环。谢谢@KennyTM

更新2

更改了代码以使用append而不是+。谢谢@Dave Webb

答案 2 :(得分:2)

一般来说,对于这类工作,您可能需要调查Biopython,它具有许多解析和处理序列的功能。

但是,您可以使用dict解决您的特定问题,这是Manoj给您的一个例子。

答案 3 :(得分:2)

比较长的字母序列将是非常低效的。比较序列的散列会更快。 Python提供了两种使用哈希的内置数据类型:setdict。最好在这里使用dict,因为我们可以存储所有匹配的行号。

我假设文件在备用行上有标识符和标签,所以如果我们在新行上拆分文件文本,我们可以将一行作为id,将下一行作为匹配的序列。

然后我们使用序列作为键的dict。相应的值是具有此序列的id列表。通过使用defaultdict from collections,我们可以轻松处理不在dict中的序列的情况;如果在defaultdict自动为我们创建值之前未使用该密钥,则在此情况下为空list

因此,当我们完成整个文件的工作时,dict的值实际上将是list list个,每个条目都包含共享序列的ID。然后我们可以使用列表推导来提取有趣的值,即序列使用多个id的条目。

from collections import defaultdict
lines = filetext.split("\n")
sequences = defaultdict(list)

while (lines):
    id = lines.pop(0)
    data = lines.pop(0)
    sequences[data].append(id)

results = [match for match in sequences.values() if len(match) > 1]
print results