如何并行化这个Python for循环?

时间:2016-03-26 13:05:51

标签: python image-processing parallel-processing

我正在处理需要并行化的图像处理问题。我已经看到几个示例显示在Python中使用并行处理,但所有这些示例的输入都是1-D数组。 因此,我正在寻找一种方法来并行化对图像执行两个过程的函数。以下代码是我需要并行化的代码:

for i in arange(0, shape(img)[0] - window_size[0], 10):
    for j in arange(0, shape(img)[1] - window_size[1], 10):
        Process1 = Do_something(img[i: i + winSize[0], j: j + winSize[1]])
        Process2 = Do_something(Process1)

如何对这个嵌套循环进行并行化?

1 个答案:

答案 0 :(得分:2)

我不完全确定变量是什么意思或Do_something()函数的作用是什么,但这是使它并行的一般方法:

import concurrent.futures
import functools

def process_stuff(i, j, img, winSize):
    Process1 = Do_something(img[i: i + winSize[0], j: j + winSize[1]])
    Process2 = Do_something(Process1)

with concurrent.futures.ProcessPoolExecutor() as executor:
    for i in arange(0, shape(img)[0] - window_size[0], 10):
        for j in arange(0, shape(img)[1] - window_size[1], 10):
            executor.submit(process_stuff, i, j, img, winSize)

此解决方案适用于Python 3.2及更高版本。旧版本可能使用multiprocessing模块。

如果您希望以更有效的方式获得返回值,这是另一种方式:

import concurrent.futures
import functools
import itertools
import operator

def process_stuff(i, j, img, winSize):
    Process1 = Do_something(img[i: i + winSize[0], j: j + winSize[1]])
    Process2 = Do_something(Process1)

with concurrent.futures.ProcessPoolExecutor() as executor:
    i_iterator = arange(0, shape(img)[0] - window_size[0], 10)
    j_iterator = arange(0, shape(img)[1] - window_size[1], 10)
    product = itertools.product(i_iterator, j_iterator)
    iter1, iter2 = itertools.tee(product)
    i_iterator = map(operator.itemgetter(0), iter1)
    j_iterator = map(operator.itemgetter(1), iter2)

    do_process = functools.partial(process_stuff, img=img, winSize=winSize)
    executor.map(do_process, i_iterator, j_iterator)

这有点复杂,但我在这里做的是获取product()i的所有组合的j,将ij分成两个迭代器,map(),迭代器作为变量。

<强>更新

我最好的选择是,阻碍你的是将图像传输到不同的进程。 这只会传输图像的相应部分:

import concurrent.futures
import itertools

def process_stuff(img_part):
    Process1 = Do_something(img_part)
    Process2 = Do_something(Process1)

with concurrent.futures.ProcessPoolExecutor() as executor:
    i_iterator = arange(0, shape(img)[0] - window_size[0], 10)
    j_iterator = arange(0, shape(img)[1] - window_size[1], 10)
    product = itertools.product(i_iterator, j_iterator)
    parts_generator = (img[i: i + winSize[0], j: j + winSize[1]]
                       for i, j in product)

    executor.map(process_stuff, parts_generator)