我需要一次生成许多样本,它们具有相同的分布类型,但参数不同。我尝试了以下代码:
a = np.array([1,2,3])
size = 5
sample = sps.norm.rvs(size=size, loc=a)
但是我收到以下错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/<me>/.pyenv/versions/study/lib/python3.5/site-packages/scipy/stats/_distn_infrastructure.py", line 933, in rvs
args, loc, scale, size = self._parse_args_rvs(*args, **kwds)
File "<string>", line 6, in _parse_args_rvs
File "/Users/<me>/.pyenv/versions/study/lib/python3.5/site-packages/scipy/stats/_distn_infrastructure.py", line 847, in _argcheck_rvs
raise ValueError("size does not match the broadcast shape of "
ValueError: size does not match the broadcast shape of the parameters.
认为尺寸参数可能也是3号大小的ndy数组,我做了以下几点:
size = np.array([5,5,5])
只有同样的例外才会受到欢迎:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/<me>/.pyenv/versions/study/lib/python3.5/site-packages/scipy/stats/_distn_infrastructure.py", line 933, in rvs
args, loc, scale, size = self._parse_args_rvs(*args, **kwds)
File "<string>", line 6, in _parse_args_rvs
File "/Users/<me>/.pyenv/versions/study/lib/python3.5/site-packages/scipy/stats/_distn_infrastructure.py", line 847, in _argcheck_rvs
raise ValueError("size does not match the broadcast shape of "
ValueError: size does not match the broadcast shape of the parameters.
认为文档可能是答案,我做了help(sps.norm.rvs)
,看到以下内容:
arg1, arg2, arg3,... : array_like
The shape parameter(s) for the distribution (see docstring of the
instance object for more information).
我不太确定实例对象是什么,所以我提到了this问题,并在help(sps.norm)
中输入,只是为了看到答案仍然未知:
rvs(self, *args, **kwds)
Random variates of given type.
Parameters
----------
arg1, arg2, arg3,... : array_like
The shape parameter(s) for the distribution (see docstring of the
instance object for more information).
我在哪里可以找到所需的文档字符串,更重要的是,如何使用不同的参数一次生成多个样本?
答案 0 :(得分:2)
rvs
方法广播,但size
参数必须是结果的最终大小。如果您有3个位置值,并且想要为每个位置值绘制5个样本,则可以使用size=(5, 3)
:
In [118]: from scipy.stats import norm
In [119]: a = np.array([1, 2, 4])
In [120]: norm.rvs(loc=a, scale=0.05, size=(5, 3))
Out[120]:
array([[ 1.01730871, 2.01713648, 3.96844145],
[ 0.96102855, 2.03925685, 3.93189097],
[ 0.98847545, 1.98229486, 4.00753205],
[ 0.99843892, 1.95899283, 3.98745337],
[ 1.01457605, 1.97508746, 4.07114077]])
如果使用此技术,请确保至少有scipy版本0.18.0。以前的版本在rvs
方法的广播行为中有a bug。
这是一个更复杂的例子:
假设您有3个位置值和2个比例值,并且对于每对, 你想画5个样本。此外,您希望结果的形状 是(3,2,5)。
以下是位置和比例数组:
In [136]: a = np.array([1, 2, 4])
In [137]: s = np.array([0.05, 0.001])
我们会在size=(3, 2, 5)
的调用中使用rvs()
,因此我们必须这样做
loc
和scale
参数的形状与numpy一致
广播规则。 loc
形状必须为(3, 1, 1)
,
并且scale
形状必须为(1, 2, 1)
。 (形状(2, 1)
也是一致的。)将这些微不足道的维度添加到a
,
我们可以使用None
,a[:,None,None]
进行索引,或者我们可以使用reshape
方法,a.reshape(-1, 1, 1)
。我们可以为s
做同样的事情
我们将它用作scale
参数。
所以对rvs()
的调用是
In [138]: samples = norm.rvs(loc=a[:,None,None], scale=s[None,:,None], size=(3, 2, 5))
In [139]: samples.shape
Out[139]: (3, 2, 5)
In [140]: samples[0, 0] # loc=1, scale=0.05
Out[140]: array([ 1.0343322 , 1.06019143, 0.95058855, 1.04184266, 1.00383671])
In [141]: samples[2, 1] # loc=4, scale=0.001
Out[141]: array([ 4.00106506, 4.00066642, 3.99801552, 3.99829284, 4.00114079])