繁体   English   中英

嵌套循环输出以并行方式输出字典

[英]Nested loops output to dict in parallel

我有两组数据:

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
...

dict 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]}

但是它工作了这么长时间

我在您的代码中看到很多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的长度。 运行足够快吗?

首先:将bList转换为dict。

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()}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM