【问题标题】:ipython notebook : how to parallelize external scriptipython notebook:如何并行化外部脚本
【发布时间】:2014-06-19 17:00:13
【问题描述】:

我正在尝试使用 ipython 并行库中的并行计算。但是我对此知之甚少,而且我发现很难从对并行计算一无所知的人那里阅读该文档。

有趣的是,我发现的所有教程都只是重用了文档中的示例,并具有相同的解释,在我看来,这是无用的。

基本上我想做的是在后台运行几个脚本,以便同时执行它们。在 bash 中会是这样的:

for my_file in $(cat list_file); do
    python pgm.py my_file &
done

但是 Ipython notebook 的 bash 解释器不处理后台模式。

似乎解决方案是使用 ipython 中的并行库。

我试过了:

from IPython.parallel import Client
rc = Client()
rc.block = True
dview = rc[:2] # I take only 2 engines

但后来我被困住了。我不知道如何同时运行两次(或多次)相同的脚本或 pgm。

谢谢。

【问题讨论】:

    标签: parallel-processing ipython ipython-notebook jupyter ipython-parallel


    【解决方案1】:

    一年后,我终于得到了我想要的。

    1) 使用您想要在不同 cpu 上执行的操作创建一个函数。这里只是使用!magic ipython 命令从bash 调用脚本。我想它可以与call() 函数一起使用。

    def my_func(my_file):
        !python pgm.py {my_file}
    

    使用!时不要忘记{}

    还要注意my_file 的路径应该是绝对路径,因为集群是您启动笔记本的位置(在执行jupyter notebookipython notebook 时),不一定是您所在的位置。

    2) 使用您想要的 CPU 数量启动您的 ipython notebook 集群。 等待 2s 并执行以下单元格:

    from IPython import parallel
    rc = parallel.Client()
    view = rc.load_balanced_view()
    

    3) 获取要处理的文件列表:

    files = list_of_files
    

    4) 将您的函数与您的所有文件异步映射到您刚刚创建的引擎的view。 (不确定措辞)。

    r = view.map_async(my_func, files)
    

    当它运行时,您可以在笔记本上做其他事情(它在“background”中运行!)。您还可以调用r.wait_interactive(),它以交互方式枚举已处理的文件数、到目前为止花费的时间以及剩余的文件数。这将阻止您运行其他单元格(但您可以中断它)。

    如果您的文件多于引擎,不用担心,一旦引擎完成 1 个文件,它们就会被处理。

    希望这对其他人有帮助!

    本教程可能会有所帮助:

    http://nbviewer.ipython.org/github/minrk/IPython-parallel-tutorial/blob/master/Index.ipynb

    还要注意我还有IPython 2.3.1,我不知道自从Jupyter之后它是否改变了。

    编辑:仍然适用于 Jupyter,请参阅 here for difference and potential issues you may encounter


    请注意,如果您在函数中使用外部库,则需要将它们导入不同的引擎:

    %px import numpy as np
    

    %%px
    import numpy as np
    import pandas as pd
    

    变量和其他函数也一样,需要推送到引擎命名空间:

    rc[:].push(dict(
                    foo=foo,
                    bar=bar))
    

    【讨论】:

    • 感谢您的回答,即使在 Jupyter Lab 上,这项工作也很完美!
    【解决方案2】:

    如果您尝试并行执行一些外部脚本,则不需要使用 IPython 的并行功能。复制bash的并行执行可以通过subprocess模块​​实现,如下:

    import subprocess
    
    procs = []
    for i in range(10):
        procs.append(subprocess.Popen(['ls', '/Users/shad/tmp/'], stdout=subprocess.PIPE))
    
    results = []
    for proc in procs:
        stdout, _ = proc.communicate()
        results.append(stdout)
    

    请注意,如果您的子进程生成大量输出,该进程将阻塞。如果你打印输出(结果),你会得到:

    print results
    
    ['file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n']
    

    【讨论】:

    • 感谢您的回答。你能解释一下打电话给os.popen("""the_bash_script_above""") 的区别吗?和/或解释communicate 部分?
    • os.popen 自 Python 2.6 起已弃用。在您要求 stdout 或 stderr 作为 PIPE 的进程中,communicate() 方法返回标准输出和标准错误。在此处查看子流程模块的文档:docs.python.org/2/library/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    相关资源
    最近更新 更多