2014-06-27 14 views
2

我都存儲在一個列表的列表數據組織像這樣:如何倉許多類別的組合(72個變量)在Python列表

lst = [ 
     ['FHControl', G, A] 
     ['MNHDosed', G, C] 
     ] 

對於LST行:行[0]共有的是12個類別(我在上面的示例代碼中列出了兩個)。對於行[1]和行[2],我只關心這些字母組合中的6個。因此,我在lst中每行有72個可能的數據組合,並且需要計算每個組合的實例,而不必編寫數十個嵌套的if循環。

我試圖創建兩個函數來解析這些列表和bin這72個組合的發生率。我如何使用兩個函數,比如我正在開始寫下面來更新這些變量?我是否需要將字典構造爲類變量,以便在迭代這兩個函數時可以繼續更新它們?任何指導都會很棒!

下面是代碼我目前初始化所有72個變量到6周的字典(爲字母6種組合中的行[1]和行[2]):

def baseparser(lst): 
    TEMP = dict.fromkeys('FHDosed FHControl FNHDosed FNHControl ' 
         'FTDosed FTControl MHDosed MHControl ' 
         'MNHDosed MNHControl MTDosed MTControl'.split(), 0) 
    TRI_1, TRI_2, TRV_1, TRV_2, TRV_3, TRV_4 = ([dict(TEMP) for i in range(6)]) 

    for row in lst: 
     if row[0] == 'FHDosed': 
      binner(row[0], row[1], row[2]) 
     if row[0] == 'FHControl': 
      binner(row[0], row[1], row[2]) 
     etc. 

def binner(key, q, s): 
    if (q == 'G' and s == 'A') or (q =='C' and s =='T'): 
     TRI_1[key] += 1 
    elif (q == 'A' and s == 'G') or (q =='T' and s =='C'): 
     TRI_2[key] += 1 
    elif (q == 'G' and s == 'T') or (q =='C' and s =='A'): 
     TRV_1[key] += 1 
    elif (q == 'G' and s == 'C') or (q =='C' and s =='G'): 
     TRV_1[key] += 1 
    elif (q == 'A' and s == 'T') or (q =='T' and s =='A'): 
     TRV_1[key] += 1 
    elif (q == 'A' and s == 'C') or (q =='T' and s =='G'): 
     TRV_1[key] += 1 
+0

不'binner'取決於兩個參數或三個?如果它只依賴於'q'和's'這些似乎是一個字母的字符串,那麼爲什麼在調用'binner'之前你需要if語句,比如'if [0] =='FHDosed'',而且shouldn'它是'binner(row [1],row [2])'而不是'binner(row [0],row [1],row [2])''? – unutbu

+0

啊你說得對。我不清楚。我認爲binner應該依賴於三個參數,第一個參數用於確定應調用適當字典中的哪個鍵來修改值(每個實例爲+ = 1)。第二個參數被if循環用來選擇開始選擇哪個字典。我將編輯我的代碼以反映。 – clintval

+0

無論'row [0]'等於什麼,調用'binner'似乎都沒有區別。有沒有細節,你離開了? – dawg

回答

4

您的代碼可以簡化到:

TEMP = dict.fromkeys('''FHDosed FHControl FNHDosed FNHControl FTDosed FTControl MHDosed 
         MHControl MNHDosed MNHControl MTDosed MTControl'''.split(), 0) 
TRI_1, TRI_2, TRV_1, TRV_2, TRV_3, TRV_4 = [TEMP.copy() for i in range(6)] 

dmap = { 
    ('G', 'A'): TRI_1, 
    ('C', 'T'): TRI_1, 
    ('A', 'G'): TRI_2, 
    ('T', 'C'): TRI_2,   
    ('G', 'C'): TRV_1, 
    ('C', 'G'): TRV_1,   
    ('A', 'T'): TRV_1, 
    ('T', 'A'): TRV_1,   
    } 

for row in lst: 
    key, q, s = row 
    dmap[q, s][key] += 1 

另一種可能是使用一個字典類型的字典代替6-類型的字典:

TEMP = dict.fromkeys('''FHDosed FHControl FNHDosed FNHControl FTDosed FTControl MHDosed 
         MHControl MNHDosed MNHControl MTDosed MTControl'''.split(), 0) 
TR = {key:TEMP.copy() for key in ('TRI_1', 'TRI_2', 'TRV_1', 'TRV_2', 'TRV_3', 'TRV_4')} 


dmap = { 
    ('G', 'A'): 'TRI_1', 
    ('C', 'T'): 'TRI_1', 
    ('A', 'G'): 'TRI_2', 
    ('T', 'C'): 'TRI_2', 
    ('G', 'C'): 'TRV_1', 
    ('C', 'G'): 'TRV_1', 
    ('A', 'T'): 'TRV_1', 
    ('T', 'A'): 'TRV_1',   
    } 

lst = [ 
     ['FHControl', 'G', 'A'], 
     ['MNHDosed', 'G', 'C'] 
     ] 

for row in lst: 
    key, q, s = row 
    TR[dmap[q, s]][key] += 1 

print(TR) 

這樣做的好處是你的命名空間中有更少的字典,並且以後可以使用字典的dict而不是硬編碼6個字典來重構代碼。


跟進Midnighter的建議,如果你有pandas,你可以用一個數據幀替換類型的字典的字典。然後對的頻率可以使用pd.crosstabs這樣計算:

import pandas as pd 

dmap = { 
    'GA': 'TRI_1', 
    'CT': 'TRI_1', 
    'AG': 'TRI_2', 
    'TC': 'TRI_2', 
    'GC': 'TRV_1', 
    'CG': 'TRV_1', 
    'AT': 'TRV_1', 
    'TA': 'TRV_1',   
    } 

lst = [ 
     ['FHControl', 'G', 'A'], 
     ['MNHDosed', 'G', 'C'] 
     ] 

df = pd.DataFrame(lst, columns=['key', 'q', 's']) 
df['tr'] = (df['q']+df['s']).map(dmap) 

print(df) 
#   key q s  tr 
# 0 FHControl G A TRI_1 
# 1 MNHDosed G C TRV_1 

print(pd.crosstab(rows=[df['key']], cols=[df['tr']])) 

產生

tr   TRI_1 TRV_1 
key      
FHControl  1  0 
MNHDosed  0  1 
+0

它的工作!這將使未來更容易擴展腳本。我會仔細研究熊貓...在閱讀完一些資料後,我可能會有更多的應用程序,熊貓將是最佳選擇。獎勵! – clintval

+0

@clintval:感謝您的糾正。 – unutbu

相關問題