读取长度为120 nt的常规fasta文件:'single_mapped.fa'
一个CSV文件包含10000个20-mer和每个20mer的计数:'20frequent_20mers.txt',如下所示:
AAAAAGTATAGGAGATAGAA 35
AAAAATAGGAGGACTATTCA 26
AAAAATAGGAGGACTATTTA 24
AAAAATAGGAGGCCTATTCA 62
我想通过single_mapped.fa,计算每次读取20frequent_20mers.txt中所有20-mer的累计计数,即读取:
我的代码:
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)
当我单独运行它们时,每个循环都运行良好,但是没有像上面那样工作,有人能告诉我哪里出错了吗?或者是否有更聪明有效的方法来做到这一点?提前谢谢!
答案 0 :(得分:2)
使用您拥有的代码,您需要从头开始为每个序列和i
值重新读取您的kmer文件。这将是非常缓慢的,应该避免。由于您没有将文件指针移回到开头,因此它只能工作一次。
可以通过在for row in kmer_list:
行之前添加来移动文件指针:
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
。
答案 1 :(得分: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)