加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python-3.x – 通过concurrent.futures多处理填充numpy数组

发布时间:2020-12-20 13:13:06 所属栏目:Python 来源:网络整理
导读:我正在寻求使用多处理来填充大型numpy数组.我已经完成了文档中的并发期货示例,但没有获得足够的理解来修改用法. 这是我想要做的简化版本: import numpyimport concurrent.futuressquares = numpy.empty((20,2))def make_square(i,squares): print('iteratio
我正在寻求使用多处理来填充大型numpy数组.我已经完成了文档中的并发期货示例,但没有获得足够的理解来修改用法.

这是我想要做的简化版本:

import numpy
import concurrent.futures

squares = numpy.empty((20,2))

def make_square(i,squares):
    print('iteration',i)
    squares[i,0],squares[i,1] = i,i ** 2

with concurrent.futures.ProcessPoolExecutor(2) as executor: 
    for i in range(20):
        executor.submit(make_square,i,squares)

输出运行如下:

iteration 1
iteration 0
iteration 2
iteration 3
iteration 5
iteration 4
iteration 6
iteration 7
iteration 8
iteration 9
iteration 10
iteration 11
iteration 12
iteration 13
iteration 15
iteration 14
iteration 16
iteration 17
iteration 18
iteration 19

很好地证明了该函数并发运行.但是正方形数组仍然是空的.

填充正方形数组的正确语法是什么?

其次,使用.map会更好吗?

提前致谢!

17年8月2日
哇.所以我徘徊在reddit-land,因为我不想接受这个问题.很高兴回到stackoverflow.谢谢@ilia w495 nikitin和@donkopotamus.这是我在reddit中发布的内容,它更详细地解释了这个问题的背景.

The posted code is an analogy of what I'm trying to do,which is populating 
a numpy array with a relatively simple calculation (dot product) involving 
two other arrays. The algorithm depends on a value N which can be anything 
from 1 on up,though we won't likely use a value larger than 24.

I'm currently running the algorithm on a distributed computing system and  
the N = 20 versions take longer than 10 days to complete. I'm using dozens 
of cores to obtain the required memory,but gaining none of the benefits of 
multiple CPUs. I've rewritten the code using numba which makes lower N 
variants superfast on my own laptop which can't handle the memory 
requirements for larger Ns,but alas,our distributed computing environment 
is not currently able to install numba. So I'm attempting concurrent.futures 
to take advantage of the multiple CPUs in our computing environment in the 
hopes of speeding things up.

所以这不是时间密集的计算,而是1600万次迭代.初始化的数组是N x 2 ** N,即上述代码中的范围(16777216).

可能是因为通过多处理填充数组是不可能的.

解决方法

这里的问题是ProcessPoolExecutor将在单独的进程中执行一个函数.

由于这些是单独的进程,具有单独的内存空间,因此您不能指望它们对数组(正方形)所做的任何更改将反映在父级中.因此,您的原始数组不会改变(正如您所发现的那样).

您需要执行以下任一操作:

>使用ThreadPoolExecutor,但在一般情况下要注意,你仍然不应该尝试修改多个线程中的全局变量;
>重新编写代码,让您的进程/线程执行某种(昂贵的)计算并返回结果.

后者看起来像这样:

squares = numpy.zeros((20,2))

def make_square(i):
    print('iteration',i)

    # compute expensive data here ...

    # return row number and the computed data
    return i,([i,i**2])

with concurrent.futures.ProcessPoolExecutor(2) as executor: 
    for row,result in executor.map(make_square,range(20)):
        squares[row] = result

这将产生您期望的结果:

[[   0.    0.]
 [   1.    1.]
 [   2.    4.]
 ...
 [  18.  324.]
 [  19.  361.]]

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读