在并行 Python 中随机抽取许多样本



我正在尝试重复运行一个需要一些位置参数并涉及随机数生成的函数(以生成分布的许多样本(。对于MWE,我认为这涵盖了一切:

import numpy as np
import multiprocessing as mup
from functools import partial
def rarr(xsize, ysize, k):
return np.random.rand(xsize, ysize)
def clever_array(nsamp, xsize=100, ysize=100, ncores=None):
np.random.seed()
if ncores is None:
p = mup.Pool()
else:
p = mup.Pool(ncores)
out = p.map_async( partial(rarr, xsize, ysize), range(nsamp))
p.close()
return np.array(out.get())

请注意,rarr(( 的最后一个位置参数只是一个虚拟变量,因为我使用的是 map_async((,它需要一个可迭代变量。现在,如果我运行%timeit clever_array(500, ncores = 1)我会得到 208 毫秒,而%timeit clever_array(500, ncores = 5)需要 149 毫秒。所以肯定有某种并行性发生(对于这个 MWE来说,加速并不是非常令人印象深刻,但在我的真实代码中是不错的(。

但是,我想知道一些事情 - 除了作为可迭代变量传递rarr()的虚拟变量之外,是否有更自然的实现来map_async运行这么多次?有没有明显的方法可以将xsizeysize参数传递给partial()以外的rarr()?除了每次初始化不同的 random.seed(( 之外,有没有办法确保不同内核的不同结果?

感谢您的任何帮助!

通常,当我们使用多处理时,我们期望每次调用函数都会产生不同的结果,因此多次调用同一个函数是没有意义的。为了保证采样输出的随机性,最好将随机状态(种子(与函数本身分开。numpy官方文档推荐的最佳方法是使用通过np.random.default_rng([seed])创建的np.random.Generator对象。有了它,我们可以修改您的代码以

import numpy as np
import multiprocessing as mup
from functools import partial
def rarr(xsize, ysize, rng):
return rng.random((xsize, ysize))
def clever_array(nsamp, xsize=100, ysize=100, ncores=None):
if ncores is None:
p = mup.Pool()
else:
p = mup.Pool(ncores)
out = p.map_async(partial(rarr, xsize, ysize), map(np.random.default_rng, range(nsamp)))
p.close()
return np.array(out.get())

相关内容

  • 没有找到相关文章

最新更新