Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Python多处理编写分块数组_Python_Arrays_Multiprocessing - Fatal编程技术网

用Python多处理编写分块数组

用Python多处理编写分块数组,python,arrays,multiprocessing,Python,Arrays,Multiprocessing,我知道有很多关于类似问题的话题,比如,或者,但我就是不明白。。。很抱歉再次询问 我需要用一个巨大的数组来做一些事情,并希望通过将它拆分成块并在这些块上运行我的函数来加快速度,每个块都在自己的进程中运行。问题是:从一个数组中剪切块,然后将结果写入一个新的公共数组。这就是我迄今为止所做的最起码的工作示例;不要介意阵列成形,这对于我的实际情况是必要的: import numpy as np import multiprocessing as mp def calcArray(array, block

我知道有很多关于类似问题的话题,比如,或者,但我就是不明白。。。很抱歉再次询问

我需要用一个巨大的数组来做一些事情,并希望通过将它拆分成块并在这些块上运行我的函数来加快速度,每个块都在自己的进程中运行。问题是:从一个数组中剪切块,然后将结果写入一个新的公共数组。这就是我迄今为止所做的最起码的工作示例;不要介意阵列成形,这对于我的实际情况是必要的:

import numpy as np
import multiprocessing as mp

def calcArray(array, blocksize, n_cores=1):
    in_shape = (array.shape[0] * array.shape[1], array.shape[2])
    input_array = array[:, :, :array.shape[2]].reshape(in_shape)
    result_array = np.zeros(array.shape)
    # blockwise loop
    pix_count = array.size
    for position in range(0, pix_count, blocksize):
        if position + blocksize < array.shape[0] * array.shape[1]:
            num = blocksize
        else:
            num = pix_count - position
        result_part = input_array[position:position + num, :] * 2
        result_array[position:position + num] = result_part
    # finalize result
    final_result = result_array.reshape(array.shape)
    return final_result

if __name__ == '__main__':
    start = time.time()
    img = np.ones((4000, 4000, 4))
    result = calcArray(img, blocksize=100, n_cores=4)
    print 'Input:\n', img
    print '\nOutput:\n', result
代码运行并真正启动了我分配的数字进程,但与旧方法相比,只使用循环需要3秒,而不是1分钟。这里肯定缺少一些东西。

核心函数是pool.apply\u async和handler.get

我最近一直在研究相同的函数,发现制作一个标准的实用函数很有用。平衡_parallel以并行方式将函数fn应用于矩阵a。在每个元素上显式应用函数。 我我分割数组的方式是np.array\u split。您可以改为使用块方案。 二,。在收集结果时,我使用concat而不是分配给空矩阵。没有共享内存

from multiprocessing import cpu_count, Pool

def balanced_parallel(fn, a, processes=None, timeout=None):
    """ apply fn on slice of a, return concatenated result """
    if processes is None:
        processes = cpu_count()
    print('Parallel:\tstarting {} processes on input with shape {}'.format(processes, a.shape))
    results = assigned_parallel(fn, np.array_split(a, processes), timeout=timeout, verbose=False)
    return np.concatenate(results, 0)


def assigned_parallel(fn, l, processes=None, timeout=None, verbose=True):
    """ apply fn on each element of l, return list of results """
    if processes is None:
        processes = min(cpu_count(), len(l))
    pool = Pool(processes=processes)
    if verbose:
        print('Parallel:\tstarting {} processes on {} elements'.format(processes, len(l)))

    # add jobs to the pool
    handler = [pool.apply_async(fn, args=x if isinstance(x, tuple) else (x, )) for x in l]

    # pool running, join all results
    results = [handler[i].get(timeout=timeout) for i in range(len(handler))]

    pool.close()
    return results
在你的情况下,fn是

后续行动: 为了实现并行化,您的循环应该如下所示

handles = []
for position in range(0, pix_count, BLOCKSIZE):
    if position + BLOCKSIZE < ARRAY.shape[0] * ARRAY.shape[1]:
        num = BLOCKSIZE
    else:
        num = pix_count - position
    handle = pool.apply_async(func=calculate, args=(input_array[position:position + num, :], ))
    handles.append(handle)

# multiple handlers exist at this moment!! Don't `.get()` yet
results = [h.get() for h in handles]
results = np.concatenate(results, axis=0)

好吧,至少它似乎起作用了:现在我必须理解它,给我一些时间让我的头脑清醒一下,然后我会接受它。谢谢大家!@s6hebern抱歉,如果它太长了:我已经多次遇到这个问题,所以我决定制定一个通用的解决方案。你可以只接受我根据你的答案编辑的基本代码,你看到我遗漏了什么吗?对我来说,代码看起来根本不起作用all@s6hebern在应用下一个作业之前,您会得到作业的结果,从而强制一个接一个地完成作业。只需应用所有作业,然后获得所有results@s6hebernaka一个循环用于apply,另一个循环用于get
def _fn(matrix_part): return matrix_part * 2
result = balanced_parallel(_fn, img)
handles = []
for position in range(0, pix_count, BLOCKSIZE):
    if position + BLOCKSIZE < ARRAY.shape[0] * ARRAY.shape[1]:
        num = BLOCKSIZE
    else:
        num = pix_count - position
    handle = pool.apply_async(func=calculate, args=(input_array[position:position + num, :], ))
    handles.append(handle)

# multiple handlers exist at this moment!! Don't `.get()` yet
results = [h.get() for h in handles]
results = np.concatenate(results, axis=0)