2015-06-22 54 views
0

我用下面的字典理解薩姆選擇的元素使用一個襯墊代替for循環

dimer = {(ab+cd):{"1":0,"2":0,"3":0} for cd in 'ACGT' for ab in 'ACGT'} 

以產生類型的字典的一個字典的,二聚體:

dimer = {"AA":{"1":0,"2":0,"3":0}, "AC":{"1":0,"2":0,"3":0}, "AG":{"1":0,"2":0,"3":0}, "AT":{"1":0,"2":0,"3":0}, "CA":{"1":0,"2":0,"3":0}, "CC":{"1":0,"2":0,"3":0}, "CG":{"1":0,"2":0,"3":0}, "CT":{"1":0,"2":0,"3":0}, "GA":{"1":0,"2":0,"3":0}, "GC":{"1":0,"2":0,"3":0}, "GG":{"1":0,"2":0,"3":0}, "GT":{"1":0,"2":0,"3":0}, "TA":{"1":0,"2":0,"3":0}, "TC":{"1":0,"2":0,"3":0}, "TT":{"1":0,"2":0,"3":0}, "TG":{"1":0,"2":0,"3":0}} 

然而,現在我想總結一下選定的元素,

如果我把它們硬編碼出來,它會像

total_A = dimer["AA"]["1"]+dimer["CA"]["1"]+dimer["GA"]["1"]+dimer["TA"]["1"]+dimer["AA"]["2"]+dimer["CA"]["2"]+dimer["GA"]["2"]+dimer["TA"]["2"]+dimer["AA"]["3"]+dimer["CA"]["3"]+dimer["GA"]["3"]+dimer["TA"]["3"] 
total_C = dimer["AC"]["1"]+dimer["CC"]["1"]+dimer["GC"]["1"]+dimer["TC"]["1"]+dimer["AC"]["2"]+dimer["CC"]["2"]+dimer["GC"]["2"]+dimer["TC"]["2"]+dimer["AC"]["3"]+dimer["CC"]["3"]+dimer["GC"]["3"]+dimer["TC"]["3"] 
total_G = dimer["AG"]["1"]+dimer["CG"]["1"]+dimer["GG"]["1"]+dimer["TG"]["1"]+dimer["AG"]["2"]+dimer["CG"]["2"]+dimer["GG"]["2"]+dimer["TG"]["2"]+dimer["AG"]["3"]+dimer["CG"]["3"]+dimer["GG"]["3"]+dimer["TG"]["3"] 
total_T = dimer["AT"]["1"]+dimer["CT"]["1"]+dimer["GT"]["1"]+dimer["TT"]["1"]+dimer["AT"]["2"]+dimer["CT"]["2"]+dimer["GT"]["2"]+dimer["TT"]["2"]+dimer["AT"]["3"]+dimer["CT"]["3"]+dimer["GT"]["3"]+dimer["TT"]["3"] 

我都拿出來簡化其使用嵌套的最好的辦法for循環:

total_0 = {i:0 for i in 'ACGT'} 
for i in 'ACGT':  
    for j in 'ACGT': 
     for k in '123': 
      total_0[i] += dimer[j+i][k] 

我想知道是否有任何使用一個襯墊,總結起來的方法?

我也有另一個嵌套的for循環:

row_sum = {i:{"1":0,"2":0,"3":0} for i in 'ACGT'} 
for i in 'ACGT':  
    for j in 'ACGT': 
     for k in '123': 
      row_sum[i][k] += float(dimer[i+j][k]) 

的硬編碼的版本是這樣的:

row_sum = {"A":{"1":0,"2":0,"3":0},"C":{"1":0,"2":0,"3":0},"G":{"G":0,"2":0,"3":0},"T":{"1":0,"2":0,"3":0}} 
for i in range(1,4,1): 
    row_sum["A"][str(i)] = float(dimer["AA"][str(i)]+dimer["AC"][str(i)]+dimer["AG"][str(i)]+dimer["AT"][str(i)]) 
    row_sum["C"][str(i)] = float(dimer["CA"][str(i)]+dimer["CC"][str(i)]+dimer["CG"][str(i)]+dimer["CT"][str(i)]) 
    row_sum["G"][str(i)] = float(dimer["GA"][str(i)]+dimer["GC"][str(i)]+dimer["GG"][str(i)]+dimer["GT"][str(i)]) 
    row_sum["T"][str(i)] = float(dimer["TA"][str(i)]+dimer["TC"][str(i)]+dimer["TG"][str(i)]+dimer["TT"][str(i)]) 

我也想知道是否有總結第二嵌套for循環的任何方法使用一個班輪?

對不起,我對Python真的很陌生。任何幫助將不勝感激!

+0

Java的新手?這是Python! – Ben

+0

爲什麼你用''1'',''2''等代替'1','2'等等?字典鍵不一定是字符串。 – amaurea

+0

@amaurea謝謝!我認爲字典鍵應該是字符串。 –

回答

0

首先,您可以使用像這樣的笛卡爾產品將3個循環合併爲一個。

from itertool import product 
row_sum = {i: {"1": 0, "2": 0, "3": 0} for i in NT} 
for i, j, k in product('ACGT', 'ACGT', '123'):  
    row_sum[i][k] += float(dimer[i + j][k]) 

這裏是一個一個套,但它可能是你很難,如果你是新來的Python

{i: sum(sum(dimer[i + j].values()) for j in 'ACGT') for i in 'ACGT'} 
+0

太棒了!那一條班輪正好是我正在尋找的。我一直在檢查列表理解文件1小時,但不能真正拿出確切的代碼來在一行中。 –

+0

非常感謝! –

+0

我已經測試過,並且認爲第二個班輪應該是{i:'ACGT'中用於j的sum(dimer [j + i] .values()),而不是'ACGT'} –

0

我不知道如何做到這一點與程序的其他部分網跟進,但可能需要切換到不同的數據結構。如果您將您的二聚體集合表示爲一個整數數組,則您將擁有您的線索,並且還會看到大量加速。您的二聚體可以例如表示這樣的:

import numpy as np 
dimer = np.zeros((4,4,3),dtype=int) 

這裏0,1,2,3中的第一個索引表示在二聚體中的第一個元素是否是A,C,G,T,和類似地對於第二個索引,而第三個索引包含您標記爲「1」,「2」或「3」的三種不同情況。所以你的dimer["AG"]["1"]會在這裏dimer[0,2,0](因爲numpy從零開始計數)。

使用結構這樣的優點是

  1. 這是更快,更高效的內存,如果你的數據集變大(如果你有每個二聚體300000元,而不是3,例如)。
  2. 有很多功能可用於處理numpy陣列。例如,np.sum(dimer,2)會給你每個二聚體元素的總數。

你想要的合計統計數據,可以計算爲:

total_0 = np.sum(dimer, (0,2)) 
row_sum = np.sum(dimer, 1) 

隨着速度的差異進行說明,您的問題大小,該dict方法與循環需要20微秒來計算total_0,而numpy總和需要5.7μs。對於1000倍大的問題,每個二聚體有3000個成員,dict方法需要22毫秒,而numpy需要31微秒。而對於1,000,000次更大的問題,dict需要24.5秒,而numpy需要24.3毫秒。所以對於大問題,numpy比使用字典快1000倍。