【问题标题】:Why is np.random.default_rng().permutation(n) preferred over the original np.random.permutation(n)?为什么 np.random.default_rng().permutation(n) 优于原始的 np.random.permutation(n)?
【发布时间】:2023-03-22 18:36:01
【问题描述】:

Numpy documentation on np.random.permutation 建议所有新代码使用随机生成器包中的np.random.default_rng()。我在文档中看到,Random Generator 包已经标准化了围绕 BitGenerator 生成各种随机分布,而不是使用我隐约熟悉的 Mersenne Twister。

我看到了一个缺点,过去只需一行代码即可完成简单的排列:

np.random.permutation(10)

现在变成了两行代码,这么简单的任务感觉有点别扭:

rng = np.random.default_rng()
rng.permutation(10)
  • 为什么这种新方法比以前的方法有所改进?
  • 为什么不像np.random.permutation 这样的现有方法只包装这个新的首选方法?
  • 假设它不会被大量调用,是否有充分的理由不将这种新方法用作单行 np.random.default_rng().permutation(10)
  • 是否有将现有代码切换到此方法的参数?

【问题讨论】:

  • 我不能给出一个有根据的答案,但我想这个想法是(类似于 C++ 所做的?)将生成器与采样器分开,并强制人们明确指定生成器。另请参阅the release comments
  • 我认为您希望在脚本开始时创建一次default_rng,然后将其与perumutationrandint 等重复使用。一次性随机调用我不会在使用新包上付出任何额外的努力。我在回答 SO 问题时没有使用它。添加新功能时,通常使用新的调用和接口添加它们比替换旧的更安全。破坏现有代码的风险较小。

标签: python numpy numpy-random


【解决方案1】:

一些上下文:

按逻辑顺序回答您的问题:

为什么像 np.random.permutation 这样的现有方法不直接包装这个新的首选方法?

可能是因为backwards compatibility concerns。即使“顶级”API 不会发生变化,其内部结构也足以被视为兼容性中断。

为什么这种新方法比以前的方法有所改进?

“默认情况下,Generator 使用 PCG64 提供的位,它比 RandomState 中使用的传统 MT19937 具有更好的统计特性。” (source)。 PCG64 文档字符串提供了更多技术细节。

假设它没有被大量调用,是否有充分的理由不将这种新方法用作单行 np.random.default_rng().permutation(10)

我非常同意如果在模块开始时添加的代码行有点尴尬。我只想指出 NumPy 文档在文档字符串示例中直接使用这种形式,例如:

n = np.random.default_rng().standard_exponential((3, 8000))

细微的差别是在模块加载/导入时实例化一个类,而在您的表单中它可能会稍后出现。但这应该是一个微小的差异(再次假设它只使用一次或几次)。如果您查看default_rng(seed) 源,当使用None 调用时,它会在对seed 进行几次快速检查后返回Generator(PCG64(seed))

是否有将现有代码切换到此方法的参数?

要传递这个,因为我没有任何接近深度的技术知识来对算法进行很好的比较,而且还因为它取决于其他一些变量,例如你是否担心让你的下游代码与旧版本 NumPy 的兼容性,其中 default_rng() 根本不存在。

【讨论】:

    猜你喜欢
    • 2019-12-06
    • 1970-01-01
    • 2011-11-16
    • 2020-09-23
    • 2013-09-09
    • 1970-01-01
    • 2015-05-04
    • 2012-07-03
    • 1970-01-01
    相关资源
    最近更新 更多