2017-07-07 150 views
0

與dict我有兩個一組數據:嵌套循環並行輸出

aDict = {'barcode1': [('barcode1', 184), ('barcode1_mut', 2)], 'barcode2': [('barcode2', 138)], 'barcode3': [('barcode3', 375)]} 
bList = [(('barcode1', 'mut1'), 184), (('barcode1_mut', 'mut2'), 2), (('barcode2', 'mut3'), 136), (('barcode2', 'mut4'), 1), (('barcode2', 'mut5'), 1), (('barcode3', 'mut6'), 373), (('barcode3', 'mut7'), 2)] 

而且我在字典aDict在列表bList和結果一致的每一個鍵,帶條碼:

>>>print(result) 
{'barcode1': {'barcode1': [('mut1', 184)], 'barcode1_mut': [('mut2', 2)]}, 
'barcode2': {'barcode2': [('mut3', 136), ('mut4', 1), ('mut5', 1)]}, 
'barcode3': {'barcode3': [('mut6', 373), ('mut7', 2)]}} 

但它對我來說太慢了。我嘗試將代碼與輸出的處理行數信息進行並行處理。但在我的實施中,每條線都由所有工人同時處理。

現在,我的實現是這樣的:

from collections import defaultdict 
import multiprocessing as mp 

def f(uniqueBarcode): 
    mutBarcodeList = [x[0] for x in aDict[uniqueBarcode]] 
    a = filter(lambda x: x[0][0] in mutBarcodeList, bList.items()) 
    d = defaultdict(tuple) 
    b = [(x[0][0], (x[0][1], x[1])) for x in a] 
    for tup in b: d[tup[0]] += (tup[1],) 
    result = {i[0]:[y for y in i[1]] for i in d.items()} 
    return result 

seqDict={} 

if __name__=='__main__': 
    cpus = mp.cpu_count() 
    pool = mp.Pool(cpus) 
    for barcode in aDict.keys(): 
     seqDict[barcode] = pool.map(f, [barcode]) 
     if len(seqDict) % 100 == 0: 
      print("Processed {} barcodes".format(len(seqDict))) 
    pool.close() 
    pool.join() 

輸出:

Processed 100 barcodes 
Processed 100 barcodes 
Processed 100 barcodes 
Processed 100 barcodes 
Processed 100 barcodes 
Processed 100 barcodes 
Processed 100 barcodes 
Processed 100 barcodes 
Processed 200 barcodes 
Processed 200 barcodes 
Processed 200 barcodes 
Processed 200 barcodes 
Processed 200 barcodes 
Processed 200 barcodes 
Processed 200 barcodes 
Processed 200 barcodes 
... 

而且字典seqDict是空的,但一定不會這樣 - 第一行第一處理過程中,第二行是第二行...第八行是第八行,第九行再行第一行等

如何正確地並行執行它?

Upd0:我適應Flomp的密碼給我

res={} 
for key in aDict: 
    if len(aDict[key]) == 1: 
     res[key] = {key:[(a[1],b) for a,b in bList if a[0] == key]} 
    elif len(aDict[key]) > 1: 
     res[key] = {x[0]:[(a[1],b) for a,b in bList if a[0] == x[0]] for x in aDict[key]} 

但它的工作這麼長時間

+0

您可能想要閱讀[mcve],並相應地重新提出您的問題。 – boardrider

+0

好吧,我在編輯我的問題 –

回答

0

起初:將bList轉換爲字典。

bDict = { 
('barcode1', 'mut1'): 184, 
('barcode1_mut', 'mut2'): 2, 
('barcode2', 'mut3'): 136, 
('barcode2', 'mut4'): 1, 
('barcode2', 'mut5'): 1, 
('barcode3', 'mut6'): 373, 
('barcode3', 'mut7'): 2} 

第二種:將值與相同的條形碼組合。

mDict = {} 
for x, y in bDict.items(): 
    if mDict.get(x[0]) == None: 
     mDict[x[0]] = [(x[1], y)] 
    else: 
     mDict[x[0]].append((x[1], y)) 
>>>print(mDict) 
{'barcode1': [('mut1', 184)], 
'barcode1_mut': [('mut2', 2)], 
'barcode2': [('mut3', 136), ('mut4', 1), ('mut5', 1)], 
'barcode3': [('mut6', 373), ('mut7', 2)]} 

第三:將結果分配給唯一的條形碼。

seqDict = {x: {y[0]: mDict[y[0]] for y in aDict[x]} for x in aDict.keys()} 
0

我看到了很多的for循環在你的代碼。這會減慢你的程序。下面是一些代碼有更好的運行時:

bcDict = {'TTCTCTTACCGGGTAC':1,'ACCTCTCGAGAATTCA':2,'TGCAGTTCTGTGCATC':3} 

bcMutCount = [(('TTCTCTTACCGGGTAC', 'ATTCAACA'), 184), 
(('ACCTCTCGAGAATTCA', 'CATCCCAC'), 136), 
(('ACCTCTCGAGAATTCA', 'CATGCCAC'), 1), 
(('ACCTCTCGAGAATTCA', 'CATCCCCC'), 1), 
(('TGCAGTTCTGTGCATC', 'TCTACATT'), 373), 
(('TGCAGTTCTGTGCATC', 'ACTGCGCA'), 2)] 


for key in bcDict: 
    print({key:[(a[1],b) for a,b in bcMutCount if a[0] == key]}) 

輸出:

{'TTCTCTTACCGGGTAC': [('ATTCAACA', 184)]} 
{'ACCTCTCGAGAATTCA': [('CATCCCAC', 136), ('CATGCCAC', 1), ('CATCCCCC', 1)]} 
{'TGCAGTTCTGTGCATC': [('TCTACATT', 373), ('ACTGCGCA', 2)]} 

請糾正我,如果這不是你想要的。上面的代碼應該在O(m * n)中運行,其中m是bcDict中的鍵數和n是bcMutCount的長度。 這是否運行得足夠快?

+0

好的,沒問題。我正在編輯帖子到最低 –

+0

我編輯了我的原始答案。 – Flomp

+0

謝謝您的回覆,但我很抱歉,我沒有完全代表bcDict變量。在這本詞典中,一個鍵映射到一個元組列表,其中可能有多個元組。現在我編輯了我的問題。 關於速度:現在我在bcDict中有〜380 000個鍵,在bcMutCount中有〜10000萬個項目:)而我作爲空氣需要並行化。早期我使用multiprocessing.pool.map(function,bcDict.keys()),但這並沒有導致進程的加速。我有兩個並行計算的實現,但它們工作緩慢。如有必要,我可以將它們添加到我的問題中。 –