2014-03-25 101 views
0

我正在处理一个简单的脚本,通过字符串循环,在这种情况下,从文件中的dna序列,并计算每个dna字符串的词频率(每次相同的单词列表,新值列表)。 我的方法(见下文)使用字典将单词存储为键并将每个单词的频率存储为一个值,但我坚持尝试将新值(对于每个后续dna记录)添加到现有的键。迭代通过现有的键和更新字典python

为RECORD1很容易(像 “GTACGTACATTT ......”),我的字典里是这样的:

{ 'GTAC': '2', 'ATTT':1,...}

然后,对于$ foo中的任何其他记录,我想更新此字典(包含相同的密钥): {'GTAC':'2','1',...,'ATTT':1, 0,...}

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') 
+1

神圣的筑巢,蝙蝠侠! – squiguy

+0

字典的'update'函数需要一个字典作为输入:'counts.update({tetranucleotide:count})'。幸运的是,这将更新或为您创建密钥。 –

+2

您可以使用itertools.product('ATGC',repeat = 4)代替那个讨厌的嵌套,看看它的价值。 – JackGibbs

回答

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 under-reported基因计数约1.049%(假设均匀随机输入)。显然某些类型的四边形比其他类型受到的影响更大:

与四分之一(“AAAA”)相比,四分之一的报价低于1/4(25%) - 也就是说,每次跟随同一封信再次。这会影响4/256四元组,导致基因总数减少0.39%。

两对四元组(“ATAT”)以1/16(6.25%)报告不足 - 每当他们再次跟随同一对字母时。这会影响12/256四元组(省略那些也是四元组),导致基因总数减少0.29%。

其中第一个字母与最后一个字母相同的四边形(“AGTA”)被1/64(1.56%)报告不足 - 每次前三个字母再次跟随。这会影响60/256四元组(省略那些也是四元组),导致基因总数减少0.37%。请注意,(2对 - 4个 - 相同)和(先 - 后 - 4个 - 相同)之间没有重叠。

与上述任何不匹配的四边形不受影响;这是剩余的180/256四边形。

+0

感谢@Hugh Bothwell,注意到.count只给出了对齐的字数,实际上我需要的是未对齐的版本,你的脚本提供了.. 不过,我拿到钥匙错误: 文件 “无题5.py”,第27行,在quad_freq 计数[四] [1] + = 1 KeyError异常: 'ATAA'” –

+0

我的错误:我正在从all_quads()而不是'ATAA'返回('A','T','A','A'),现在应该修复。 –

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:] 

事情明显提取出来的功能,什么不是。