随机数生成

Dask 的随机数例程通过结合 BitGenerator 来创建序列,并使用 Generator 来利用这些序列从不同的统计分布中进行采样,从而生成伪随机数。

自 Dask 版本 2023.2.1 起,Generator 可以用多种不同的 BitGenerator 类初始化。它暴露了许多不同的概率分布。旧版的 RandomState 随机数例程仍然可用,但被视为冻结状态,不会获得任何更新。

与 NumPy 的区别

Dask 遵循 NumPy 的随机数生成接口,但有一些差异:

  • dask.array.random 下的方法接受一个 chunks 关键字。

  • Dask 试图保持后端无关性。换句话说,你可以主要使用 CuPy 和 NumPy 互换作为随机数生成的后端。任何提供类似接口的库也应该在一定程度上工作。

注释

  • BitGenerators: 生成随机序列的对象。这些由NumPy或CuPy等后端库提供,通常是填充了32或64位随机比特序列的无符号整数词。

  • 生成器:BitGenerator 生成的随机比特序列转换为遵循特定概率分布(如均匀分布、正态分布或二项分布)的数字序列的对象,这些数字序列在指定的区间内。

  • Dask 不保证在不同版本之间使用相同的随机数生成器。这意味着由 dask.array.random 生成的新版本中的数字可能与之前的版本不同,即使使用了相同的种子和分布。随着更好的算法的发展,比特流可能会发生变化。

  • Dask 不保证生成的数字与任何第三方库的奇偶性。特别是,即使使用相同的种子和 BitGenerator,Dask 和 NumPy 或 CuPy 生成的数字也会不同。Dask 倾向于生成 SeedSequence 子序列以在并行中产生独立的随机数流。

  • dask.array.random 中导出了许多 RandomState 方法作为函数。不建议使用此用法,因为它通过一个全局 RandomState 实例实现,这在两个方面不被推荐:

    1. 它使用了全局状态,这意味着随着代码的变化,结果也会改变。

    2. 它使用的是 RandomState,而不是更现代的 Generator。

    出于向后兼容的遗留原因,我们不能更改这一点。使用 dask.array.random.default_rng() 来获取一个生成器并使用其方法。

  • Generator.integers 现在是生成离散均匀分布的整数随机数的规范方法。可以使用 endpoint 关键字来指定开区间或闭区间。这取代了 randintrandom_integers

  • Generator.random 现在是生成浮点随机数的规范方法,它取代了 random_sampledask.array.random.random 方法仍然使用 RandomState 以保持向后兼容性,在新代码中应避免使用。请改用 Generator.random

快速开始

调用 default_rng 以获取一个 Generator 的新实例,然后调用其方法从不同的分布中获取样本。默认情况下,Generator 使用由 PCG64 提供的比特,其统计特性优于 RandomState 中使用的传统 MT19937。

# Do this (new version)
import dask.array as da
rng = da.random.default_rng()
vals = rng.standard_normal(10)
more_vals = rng.standard_normal(10)

# instead of this (legacy version)
import dask.array as da
vals = da.random.standard_normal(10)
more_vals = da.random.standard_normal(10)

更多信息,请参阅 NumPy 文档