【问题标题】:Use bash to iterate python function over several files使用 bash 在多个文件上迭代 python 函数
【发布时间】:2022-08-02 21:32:32
【问题描述】:

我有一个将文件作为参数的 python 函数,我们称之为func(file)。我还有一个包含大约 100 个文件的目录,这些文件应传递给 python 脚本execute_function.py,此 python 脚本获取文件列表并将func(file) 应用于然后。将这 100 个文件细分为 4 个 25 个文件的堆栈,然后使用 execute_function.py 在 4 个不同的 python 内核中执行的最简单方法是什么?

它基本上是与 bash 的蛮力并行化。

  • 这回答了你的问题了吗? How do I split a list into equally-sized chunks?
  • 不是真的,我期望使用 bash 将文件列表拆分为 4 个列表,然后使用这些列表作为参数应用 python 函数 4 次。
  • subprocess 库允许您运行脚本/bash 命令并捕获输出,然后您可以传递调用您的 Python 函数。

标签: python bash parallel-processing


【解决方案1】:

本身不是一个 bash 答案,但您可以使用多处理来实现这一点。这是一个示例,我将一个数组拆分为 4 个块,并在独立函数中同时使用这 4 个块。

import concurrent.futures
import time


def split_array(array, num_splits):
    chunksize = len(array) // num_splits
    chunk = 0
    for i in range(num_splits):
        if i + 1 == num_splits:
            yield array[chunk:]
        else:
            yield array[chunk : chunk + chunksize]
        chunk += chunksize


def map_processes(func, iterable_):
    with concurrent.futures.ProcessPoolExecutor() as executor:
        result = executor.map(func, iterable_)
    return result


def dummy_func(l):
    for i in l:
        print(i)
        time.sleep(0.5)


if __name__ == "__main__":
    array = list(range(100))
    split_arrays = split_array(array, 4)
    map_processes(dummy_func, split_arrays)

【讨论】:

    【解决方案2】:

    使用 GNU 并行

    parallel --jobs 4 python execute_function.py ::: files*
    

    默认情况下,它会为每个 cpu-core 运行一个作业。这可以通过--jobs 进行调整。

    GNU Parallel 是一个通用的并行化器,可以轻松地在同一台机器上或在您可以通过 ssh 访问的多台机器上并行运行作业。

    如果您想在 4 个 CPU 上运行 32 个不同的作业,那么并行化的直接方法是在每个 CPU 上运行 8 个作业:

    GNU Parallel 会在完成后生成一个新进程 - 保持 CPU 处于活动状态,从而节省时间:

    安装

    出于安全原因,您应该使用软件包管理器安装 GNU Parallel,但如果 GNU Parallel 没有为您的发行版打包,您可以进行个人安装,这不需要 root 访问权限。这样做可以在 10 秒内完成:

    $ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
       fetch -o - http://pi.dk/3 ) > install.sh
    $ sha1sum install.sh | grep 883c667e01eed62f975ad28b6d50e22a
    12345678 883c667e 01eed62f 975ad28b 6d50e22a
    $ md5sum install.sh | grep cc21b4c943fd03e93ae1ae49e28573c0
    cc21b4c9 43fd03e9 3ae1ae49 e28573c0
    $ sha512sum install.sh | grep da012ec113b49a54e705f86d51e784ebced224fdf
    79945d9d 250b42a4 2067bb00 99da012e c113b49a 54e705f8 6d51e784 ebced224
    fdff3f52 ca588d64 e75f6033 61bd543f d631f592 2f87ceb2 ab034149 6df84a35
    $ bash install.sh
    

    有关其他安装选项,请参阅http://git.savannah.gnu.org/cgit/parallel.git/tree/README

    学到更多

    查看更多示例:http://www.gnu.org/software/parallel/man.html

    观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

    浏览教程:http://www.gnu.org/software/parallel/parallel_tutorial.html

    注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel

    【讨论】:

      猜你喜欢
      • 2020-10-21
      • 2021-12-12
      • 2012-07-22
      • 2018-01-19
      • 1970-01-01
      • 2020-08-15
      • 1970-01-01
      • 2017-06-25
      • 1970-01-01
      相关资源
      最近更新 更多