我有一组简单的代码,可以从Python运行Clustal Omega(蛋白质多序列比对程序):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18from Bio.Align.Applications import ClustalOmegaCommandline
segments = range(1, 9)
segments.reverse()
for segment in segments:
in_file = '1.0 - Split FASTA Files/Segment %d.fasta' % segment
out_file = '1.1 - Aligned FASTA Files/Segment %d Aligned.fasta' % segment
distmat = '1.1 - Distmats/Segment %d Distmat.fasta' % segment
cline = ClustalOmegaCommandline(infile=in_file,
outfile=out_file,
distmat_out=distmat,
distmat_full=True,
verbose=True,
force=True)
print cline
cline()
我已经在进行多序列比对(MSA)的时间进行了一些非正式测试。平均每个人需要4个小时。一个接一个地跑所有8个球,总共花了我32个小时。因此,这是我将其作为for循环运行的初衷-我可以让它运行而不必担心。
但是,我又进行了一次非正式测试-我从打印的cline中获取输出,然后将其复制并粘贴到分布在两台计算机上的8个单独的终端窗口中,并以此方式运行MSA。平均而言,每个人花了大约8个小时左右...但是由于它们都同时运行,所以我只花了8个小时就得到了结果。
在某些方面,我发现了并行处理! :D
但是我现在面临着如何使其在Python中运行的难题。我曾尝试查看以下SO帖子,但似乎仍无法围绕多处理模块的工作原理进行总结。
职位清单:
如何并行化一个简单的Python循环?
在Python 3.2中并行执行for循环
python中的并行循环
如何在python中并行化big for循环
有人愿意分享他们如何并行化此循环吗?我确实有很多循环看起来与此循环类似,在该循环中,我对文件执行了一些操作并写入了另一个文件,而无需将结果汇总到内存中。我面临的特定区别是需要执行文件I / O,而不是汇总来自循环并行运行的结果。
由于其他文章已经陈述了实现for循环并行化的多种方法,是否有特定的问题困扰您?
这些示例都不涉及文件I / O,而是涉及汇总并行运行的结果。至少,这就是我阅读这些帖子时的想法。请原谅我的无知,我仍然认为自己是许多计算概念和Python的新手。
如果您担心文件I / O,请在问题中明确说明。按照目前的情况,它与您链接的问题完全相同。但是,对于AFAIK,文件I / O没什么特别的。您只需要在进程之间使用一些锁,以避免无意义地输出到文件,就可以完成了。
@Bakuriu,我从一开始就在帖子中做到了。请阅读下面的段落。
@ericmjl尚不清楚您的问题的唯一目的是如何处理并行I / O。在编写时,它看起来像是对代码无关细节的随意评论。如果您的问题是"如何处理并行输出到文件?"然后编写它,不要只写"如何并行化此循环?"然后将"代码恰巧包含文件I / O"放到随机位置。
@Bakuriu,我接受了您的建议,并在最后一点作了编辑。但是,换句话说,仅基于阅读您的评论,就花了一段时间来消化您的发言,因为我觉得您的表现是傲慢而进取的,这消除了在SO上欢迎新手和新手的必要。我希望我们能互相尊重地交换意见,并希望您也能以这种方式阅读我的评论。
您可能正在寻找Joblib库。
让我举一个使用它的例子:
1
2
3
4
5
6
7
8
9
10
11import time
from joblib import Parallel, delayed
def long_function():
time.sleep(1)
REPETITIONS = 4
Parallel(n_jobs=REPETITIONS)(
delayed(long_function)() for _ in range(REPETITIONS))
此代码将在1秒而不是4秒内运行。
修改您的代码看起来像这样(对不起,我无法测试这是否正确):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25from joblib import Parallel, delayed
from Bio.Align.Applications import ClustalOmegaCommandline
def run(segment):
in_file = '1.0 - Split FASTA Files/Segment %d.fasta' % segment
out_file = '1.1 - Aligned FASTA Files/Segment %d Aligned.fasta' % segment
distmat = '1.1 - Distmats/Segment %d Distmat.fasta' % segment
cline = ClustalOmegaCommandline(infile=in_file,
outfile=out_file,
distmat_out=distmat,
distmat_full=True,
verbose=True,
force=True)
print cline
cline()
if __name__ =="__main__":
segments = range(1, 9)
segments.reverse()
Parallel(n_jobs=len(segments)(
delayed(run)(segment) for segment in segments)
感谢您提供的有用信息! 我想问一下,假设这是从IPython笔记本上运行的,我是否可以将if __name__ == __main__:下的部分放在一个单元格中并运行该单元格?
是的,如果其余代码已包含在先前已评估的单元格中,则可以按照说明运行它。
非常感谢,@ logc!
这在我的python版本中不起作用。它说没有这样的模块。
@ robbieboy74:您安装了Joblib库吗? 它不是标准模块
代替for segment in segments,写def f(segment),然后使用multiprocessing.Pool().map(f, segments)
弄清楚如何将其放在上下文中作为练习留给读者。
我认为使用imap代替map在这里可能合适,因为运行时很长。