用python计算fasta中的20个数字

用python计算fasta中的20个数字,python,csv,biopython,fasta,Python,Csv,Biopython,Fasta,读取长度为120 nt的常规fasta文件:“single_mapped.fa” CSV文件包含10000个20 mers,每20 mer的计数为:“20frequency_20mers.txt”,如下所示: AAAAAGTATAGGAGATAGAA 35 AAAAATAGGAGGACTATTCA 26 AAAAATAGGAGGACTATTTA 24 AAAAATAGGAGGCCTATTCA 62 我想通过single_mapped.fa,计算20frequency_2

读取长度为120 nt的常规fasta文件:“single_mapped.fa”

CSV文件包含10000个20 mers,每20 mer的计数为:“20frequency_20mers.txt”,如下所示:

AAAAAGTATAGGAGATAGAA    35
AAAAATAGGAGGACTATTCA    26
AAAAATAGGAGGACTATTTA    24
AAAAATAGGAGGCCTATTCA    62
我想通过single_mapped.fa,计算20frequency_20mers.txt中每个读取的所有20个mer的累积计数,即读取:

aaaaa-gtataggagatagaaaaaaaaaa-taggactattca,我想要61(35+26)

我的代码:

file2 = open('20frequent_20mers.txt','r')
kmer_list = csv.reader(file2, delimiter='\t')

for seq_record in SeqIO.parse("single_mapped.fa", "fasta"):
    print(seq_record.id)
    score_fre = 0
    sequence_string = str(seq_record.seq)
    for i in range(0,101):
            seq = sequence_string[i:i+20]
            for row in kmer_list:
                if row[0] == seq:
                    score_fre = score_fre + int(row[1])            
    print(score_fre)

当我单独运行它们时,每个循环都工作得很好,但是没有像上面那样工作,有人能告诉我错误来自哪里吗?或者有没有更聪明、更有效的方法?提前谢谢

使用现有的代码,您需要从一开始就为每个序列和
i
值重新读取kmer文件。这将非常缓慢,应该避免。由于您没有将文件指针移回起始位置,因此它只能工作一次

可以通过在kmer\U列表中的行的
之前添加来移动文件指针:
行:

file2.seek(0)
更好的方法是首先将所有kmer条目连同相应的计数一起加载到字典中。这样可以快速查找它们:

import csv

kmers = {}

with open('20frequent_20mers.txt') as f_kmers:
    for kmer, count in csv.reader(f_kmers, delimiter='\t'):
        kmers[kmer] = int(count)

for seq_record in SeqIO.parse("single_mapped.fa", "fasta"):
    print(seq_record.id)
    score_fre = 0
    sequence_string = str(seq_record.seq)

    for i in range(0, 101):
        seq = sequence_string[i:i+20]
        score_fre += kmers.get(seq, 0)

    print(score_fre) 

如果在字典中找不到
seq
,则返回
0
的默认值。

使用@MartinEvans字典的替代实现(不一定更好或更快),但使用
re.findall()
生成kmers以测试并使用
map
sum
代替(显式)内环:

from Bio import SeqIO
from re import findall
from itertools import repeat

kmers = {}

with open('20frequent_20mers.txt') as f_kmers:
    for line in f_kmers:
        kmer, count = line.strip().split('\t')
        kmers[kmer] = int(count)

for seq_record in SeqIO.parse("single_mapped.fa", "fasta"):
    print(seq_record.id)

    # use forward lookahead to make findall() find overlapping results;

    score_fre = sum(map(kmers.get, findall(r'(?=([ACTG]{20}))', str(seq_record.seq)), repeat(0)))

    print(score_fre)

非常感谢!!它工作完美,速度也很快!我是python的新手,但使用了大量的R和bash。据我所知,对于序列和I上的每个循环,它只是从第一行到最后一行遍历kmer文件进行搜索,但不改变它的大小。为什么只工作一次?有没有一种方法可以像你在我的代码中说的那样将文件指针移回起始位置?在读取文件时,每次读取都会移动文件指针,就像在循环中一样。循环结束后,指针将停留在末尾,因此下次进入循环时,指针将不会执行任何操作,因为没有任何内容可读取。我的方法使用Python字典快速查找kmer。这完全避免了重复读取同一个文件。