随机数生成

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 位随机比特序列的无符号整数。

  • Generators:将来自 BitGenerator 的随机比特序列转换为遵循特定概率分布(例如均匀分布、正态分布或二项分布)并在指定区间内的数值序列的对象。

  • Dask 不保证跨版本使用相同的数字生成器。这意味着即使使用相同的种子和分布,新版本由 dask.array.random 生成的数字可能与旧版本不同。随着算法的改进,比特流可能会发生变化。

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

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

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

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

    由于向后兼容的遗留原因,我们无法更改此项。请改用 dask.array.random.default_rng() 获取 Generator 实例并使用其方法。

  • 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 文档