首页 > 解决方案 > 如何让 scipy.stats.truncnorm.rvs 使用 numpy.random.default_rng()?

问题描述

我在 scipy.stats.truncnorm 中遇到了 random_state 的问题。这是我的代码:

from scipy.stats import truncnorm
from numpy.random import default_rng
rg = default_rng( 12345 )
truncnorm.rvs(0.0,1.0,size=10, random_state=rg)

我收到以下错误:

  File "test2.py", line 4, in <module>
    truncnorm.rvs(0.0,1.0,size=10, random_state=rg)
  File "/opt/anaconda3/envs/newbase/lib/python3.8/site-packages/scipy/stats/_distn_infrastructure.py", line 1004, in rvs
    vals = self._rvs(*args, size=size, random_state=random_state)
  File "/opt/anaconda3/envs/newbase/lib/python3.8/site-packages/scipy/stats/_continuous_distns.py", line 7641, in _rvs
    out = self._rvs_scalar(a.item(), b.item(), size, random_state=random_state)
  File "/opt/anaconda3/envs/newbase/lib/python3.8/site-packages/scipy/stats/_continuous_distns.py", line 7697, in _rvs_scalar
    U = random_state.random_sample(N)
AttributeError: 'numpy.random._generator.Generator' object has no attribute 'random_sample'

我正在使用 numpy 1.19.1 和 scipy 1.5.0。scipy.norm.rvs 不会出现此问题。

标签: numpyscipy

解决方案


在 scipy 1.7.1 中,问题行已更改为:

def _rvs_scalar(self, a, b, numsamples=None, random_state=None):
    if not numsamples:
        numsamples = 1

    # prepare sampling of rvs
    size1d = tuple(np.atleast_1d(numsamples))
    N = np.prod(size1d)  # number of rvs needed, reshape upon return
    # Calculate some rvs
    U = random_state.uniform(low=0, high=1, size=N)
    x = self._ppf(U, a, b)
    rvs = np.reshape(x, size1d)
    return rvs

两者都有uniform,但rg没有random_sample

In [221]: rg.uniform
Out[221]: <function Generator.uniform>
In [222]: np.random.uniform
Out[222]: <function RandomState.uniform>

np.random.random_sample有这个注释:

.. note::
    New code should use the ``random`` method of a ``default_rng()``
    instance instead; please see the :ref:`random-quick-start`.

推荐阅读