新功能与变更#
NumPy 1.17.0 引入了 Generator
作为 传统 RandomState
的改进替代品。以下是这两种实现的快速比较。
特性 |
旧版等效 |
备注 |
|
||
访问 `BitGenerator` 中的值,并将其转换为 `[0.0., 1.0)` 区间内的 `float64`。除了 `size` 关键字参数外,现在还支持 `dtype='d'` 或 `dtype='f'`,以及用于填充用户提供的数组的 `out` 关键字参数。 还支持许多其他分布。 |
||
使用 `endpoint` 关键字参数调整 `high` 区间端点的包含或排除。 |
正态分布、指数分布和伽马分布生成器使用 256 步 Ziggurat 方法,比 NumPy 在
standard_normal
、standard_exponential
或standard_gamma
中的默认实现快 2-10 倍。由于算法的改变,无法使用Generator
为这些分布或任何依赖它们的分布方法重现确切的随机值。
In [1]: import numpy.random
In [2]: rng = np.random.default_rng()
In [3]: %timeit -n 1 rng.standard_normal(100000)
...: %timeit -n 1 numpy.random.standard_normal(100000)
...:
1.88 ms +- 13.3 us per loop (mean +- std. dev. of 7 runs, 1 loop each)
3.46 ms +- 20.2 us per loop (mean +- std. dev. of 7 runs, 1 loop each)
In [4]: %timeit -n 1 rng.standard_exponential(100000)
...: %timeit -n 1 numpy.random.standard_exponential(100000)
...:
919 us +- 12.4 us per loop (mean +- std. dev. of 7 runs, 1 loop each)
2.47 ms +- 23.4 us per loop (mean +- std. dev. of 7 runs, 1 loop each)
In [5]: %timeit -n 1 rng.standard_gamma(3.0, 100000)
...: %timeit -n 1 numpy.random.standard_gamma(3.0, 100000)
...:
3.53 ms +- 39.5 us per loop (mean +- std. dev. of 7 runs, 1 loop each)
6.96 ms +- 25.1 us per loop (mean +- std. dev. of 7 runs, 1 loop each)
integers
现在是从离散均匀分布生成整数随机数的规范方法。它取代了randint
和已弃用的random_integers
。rand
和randn
方法仅通过传统RandomState
可用。Generator.random
现在是生成浮点随机数的规范方法,它取代了RandomState.random_sample
、sample
和ranf
(所有这些都是别名)。这与 Python 的random.random
一致。所有位生成器都可以通过 CTypes (
ctypes
) 和 CFFI (cffi
) 生成双精度浮点数、无符号 64 位整数和无符号 32 位整数。这使得这些位生成器可以在 numba 中使用。位生成器可以通过 Cython 在下游项目中使用。
所有位生成器都使用
SeedSequence
来将种子整数转换为初始化状态。可选的
dtype
参数接受np.float32
或np.float64
,用于为选定分布生成单精度或双精度均匀随机变量。integers
接受一个dtype
参数,可为任何有符号或无符号整数数据类型。正态分布 (
standard_normal
)标准伽马分布 (
standard_gamma
)标准指数分布 (
standard_exponential
)
In [6]: rng = np.random.default_rng()
In [7]: rng.random(3, dtype=np.float64)
Out[7]: array([0.00512656, 0.76054751, 0.5135002 ])
In [8]: rng.random(3, dtype=np.float32)
Out[8]: array([0.13016486, 0.67658764, 0.94141597], dtype=float32)
In [9]: rng.integers(0, 256, size=3, dtype=np.uint8)
Out[9]: array([100, 186, 43], dtype=uint8)
可选的
out
参数允许为选定分布填充现有数组均匀分布 (
random
)正态分布 (
standard_normal
)标准伽马分布 (
standard_gamma
)标准指数分布 (
standard_exponential
)
这使得多线程能够并行使用合适的 BitGenerator 分块填充大型数组。
In [10]: rng = np.random.default_rng()
In [11]: existing = np.zeros(4)
In [12]: rng.random(out=existing[:2])
Out[12]: array([0.7695275 , 0.73739323])
In [13]: print(existing)
[0.7695275 0.73739323 0. 0. ]
可选的
axis
参数,用于choice
、permutation
和shuffle
等方法,控制多维数组的操作轴。
In [14]: rng = np.random.default_rng()
In [15]: a = np.arange(12).reshape((3, 4))
In [16]: a
Out[16]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [17]: rng.choice(a, axis=1, size=5)
Out[17]:
array([[ 0, 1, 2, 0, 0],
[ 4, 5, 6, 4, 4],
[ 8, 9, 10, 8, 8]])
In [18]: rng.shuffle(a, axis=1) # Shuffle in-place
In [19]: a
Out[19]:
array([[ 2, 1, 0, 3],
[ 6, 5, 4, 7],
[10, 9, 8, 11]])
添加了一个从复正态分布 (complex_normal) 采样的函数