我正在处理一个循环字符串的简单脚本,在这种情况下是来自文件的dna序列,并计算每个dna字符串的字频率(每次都是相同的单词列表,新的值列表)。 我的方法(见下文)使用字典将单词作为键存储,并将每个单词的频率存储为值,但我试图将新值(对于每个后续dna记录)添加到现有键中。
对于record1来说很容易(像#34; GTACGTACATTT ......"),我的字典看起来像:
{' GTAC':' 2'' ATTT':1,....}
然后对于$ foo中的任何其他记录,我想更新此词典(包含相同的键): {&#39; GTAC&#39;:&#39; 2&#39;&#39; 1&#39;,...,&#39; ATTT&#39;:1,0,...} < / p>
from Bio import SeqIO
def tetra_freq(sequence):
counts = {}
for record in SeqIO.parse(sequence, 'fasta'):
newseq=record.seq
for base1 in ['A', 'T', 'G', 'C']:
for base2 in ['A', 'T', 'G', 'C']:
for base3 in ['A', 'T', 'G', 'C']:
for base4 in ['A','T','G','C']:
tetranucleotide = base1 + base2 + base3 + base4
count = newseq.count(tetranucleotide)
if tetranucleotide in counts.keys():
counts.update(count)
else:
counts[tetranucleotide] = count
print(counts)
tetra_freq('$foo')
答案 0 :(得分:1)
据我所知,你有一个词,比如说:
“GTACATTTCATGATTT”
这给了你:
{'GTAC':1,'ATTT':2,'CATG':1}
那么如果你看到另一个词,请说:
“GTACAATC”
你现在有:
{'GTAC':[1,1],'ATTT':[2,0],'CATG':[1,0],'AATC':[0,1}}
等等?如果我误解了,我会编辑我的回复。无论如何,这应该这样做:
from itertools import product
strings = ["GTACATTTCATGATTT", "GTACAATC"]
count_dict = {}
for poss_word in product('ATCG', repeat=4):
count_dict["".join(poss_word)] = [0] * len(strings)
for index, string in enumerate(strings):
while string:
word = string[:4]
count_dict[word][index] += 1
string = string[4:]
事情显然是从功能中提取出来的,而不是。
答案 1 :(得分:0)
从您的描述中不完全清楚您是否只查看四个字母对齐的单词,即
"GTACGTACATTT" => "GTAC", "GTAC", "ATTT"
(正如你的字典计数所暗示的那样),或者你是否正在查看任何四个字母的序列,
"GTACGTACATTT" => "GTAC", "TACG", "ACGT", "CGTA", "GTAC", "TACA", "ACAT", "CATT", "ATTT"
因为您使用str.count
似乎意味着。请注意,如果是后者,str.count
只会计算非重叠实例 - 所以"AAAAAAA".count("AAAA")
会返回1而不是您预期的4!
# assumes Python 2.7
from Bio import SeqIO
from collections import Counter
from itertools import izip, product, tee
def get_aligned_quads(seq, length=4):
args = [iter(seq)] * length
return (''.join(letters) for letters in izip(*args))
def get_unaligned_quads(seq, length=4):
args = tee(iter(seq), length)
for steps,arg in enumerate(args):
for step in range(steps):
next(arg, None)
return (''.join(letters) for letters in izip(*args))
all_quads = [''.join(seq) for seq in product("ACGT", repeat=4)]
def quad_freq(sequence, aligned=True):
get_quads = get_aligned_quads if aligned else get_unaligned_quads
counts = {quad:[] for quad in all_quads}
for i,record in enumerate(SeqIO.parse(sequence, 'fasta')):
for quad in all_quads:
counts[quad].append(0)
for quad in get_quads(record.seq):
counts[quad][i] += 1
return counts
print(quad_freq("$foo"))
编辑:我将all_quads转换为列表 - 应该快一点;
我也进行了一些模拟,并发现(假设均匀随机输入)使用.count低报告基因计数约1.049%。显然,某些类型的四边形比其他类型的四边形更受影响:
四分之一(&#34; AAAA&#34;)的四分之一被1/4(25%)报告不足 - 也就是说,每次再次跟着相同的字母。这会影响4/256个四边形,导致总基因数减少0.39%。
2对(&#34; ATAT&#34;)的四分之一被1/16(6.25%)报告不足 - 每次它们再次被同一对字母跟随。这会影响12/256个四边形(省略那些也是相同的四个),导致基因总数减少0.29%。
第一个字母与最后一个字母相同的四元组(&#34; AGTA&#34;)被1/64(1.56%)报告不足 - 每次它们再次跟着前三个字母。这会影响60/256个四边形(省略那些也是相同的四个),导致总基因数减少0.37%。请注意,(2对 - 4对相同)和(首先 - 最后 - 4 - 相同)之间没有重叠。
与上述任何一项不匹配的四元组不受影响;这是剩余的180/256个四边形。