这是一个用于计算直方图的脚本,我发现lib csv.py
花费的时间最多。我如何并行运行它?
输入文件samtools.depth.gz
的大小为14G,包含约30亿行。
SamplesList = ('Sample_A', 'Sample_B', 'Sample_C', 'Sample_D')
from collections import Counter
cDepthCnt = {key:Counter() for key in SamplesList}
cDepthStat = {key:[0,0] for key in SamplesList} # x and x^2
RecordCnt,MaxDepth = inStat('samtools.depth.gz')
print('xxx')
def inStat(inDepthFile):
import gzip
import csv
RecordCnt = 0
MaxDepth = 0
with gzip.open(inDepthFile, 'rt') as tsvfin:
tsvin = csv.DictReader(tsvfin, delimiter='\t', fieldnames=('ChrID','Pos')+SamplesList )
RecordCnt += 1
for row in tsvin:
for k in SamplesList:
theValue = int(row[k])
if theValue > MaxDepth:
MaxDepth = theValue
cDepthCnt[k][theValue] += 1
cDepthStat[k][0] += theValue
cDepthStat[k][1] += theValue * theValue
return RecordCnt,MaxDepth
有多种方法可以将大文件读取成块并将其与列表一起分发,例如https://stackoverflow.com/a/30294434/159695:
bufsize = 65536
with open(path) as infile:
while True:
lines = infile.readlines(bufsize)
if not lines:
break
for line in lines:
process(line)
但是,csv.DictReader
仅接受文件句柄。
有一种方法可以在https://gist.github.com/jbylund/c37402573a896e5b5fc8处分割为临时文件,我想知道是否可以使用fifo即时进行分割。
我只是发现csv.DictReader
接受任何支持迭代器协议的对象,并在每次调用其 next ()方法时都返回一个字符串-文件对象和列表对象均适用。 / p>
我已修改inStat()
以接受行。您能帮我完成statPool()
吗?
def statPool(inDepthFile):
import gzip
RecordCnt = 0
MaxDepth = 0
cDepthCnt = {key:Counter() for key in SamplesList}
cDepthStat = {key:[0,0,0,0,0] for key in SamplesList} # x and x^2
with gzip.open(inDepthFile, 'rt') as tsvfin:
while True:
lines = tsvfin.readlines(ChunkSize)
if not lines:
break
with Pool(processes=4) as pool:
res = pool.apply_async(inStat,[lines])
iRecordCnt,iMaxDepth,icDepthCnt,icDepthStat = res.get()
RecordCnt += iRecordCnt
if iMaxDepth > MaxDepth:
MaxDepth = iMaxDepth
for k in SamplesList:
cDepthCnt[k].update(icDepthCnt[k])
cDepthStat[k][0] += icDepthStat[k][0]
cDepthStat[k][1] += icDepthStat[k][1]
return RecordCnt,MaxDepth,cDepthCnt,cDepthStat
我认为asyncio.Queue
似乎是向多个csv.DictReader
工作人员进行管道传送的好方法。
答案 0 :(得分:0)
在全局范围内查找内容要比在本地范围内查找内容花费时间更长。
您要进行很多查找-我建议将代码更改为:
cDepthCnt = {key:Counter() for key in SamplesList}
cDepthStat = {key:[0,0] for key in SamplesList} # x and x^2
RecordCnt,MaxDepth = inStat('samtools.depth.gz', cDepthCnt, cDepthStat)
print('xxx')
def inStat(inDepthFile, depthCount, depthStat):
# use the local depthCount, depthStat
加快部分速度。
一遍又一遍地访问相同的键时并行运行会在这些值上引入锁定,以避免发生意外-锁定/解锁也需要时间。您将不得不看看它是否更快。
您要做的就是对值求和-您可以对数据进行分区,并将4个部分用于4个(乘2)字典,然后将这4个字典加到全局字典中以避免锁定。