Numpy “你能”吗;强迫`scipy.stats.norm.rvs`是否输出正值?

Numpy “你能”吗;强迫`scipy.stats.norm.rvs`是否输出正值?,numpy,random,scipy,statistics,distribution,Numpy,Random,Scipy,Statistics,Distribution,这可能是一个幼稚的问题,但我找不到任何关于它的帖子,所以我认为问这个问题可能有用。我发现一个分布可能很适合我的数据,但我所有的数据点在现实生活中都是积极的(-1是不可能的) 有没有办法强制.rvs只输出正值? 我想到了一些方法,但它们似乎占用了大量的CPU资源,比如制造出比我需要的更多的值,然后对所有正值和np.random.choice进行布尔掩码有更好的方法吗? 我在文档中没有看到任何关于这方面的信息: 我发现这并没有产生任何结果: 及 取决于您希望保持的分布的真实程度。如果你只想要正值,

这可能是一个幼稚的问题,但我找不到任何关于它的帖子,所以我认为问这个问题可能有用。我发现一个分布可能很适合我的数据,但我所有的数据点在现实生活中都是积极的(-1是不可能的)

有没有办法强制
.rvs
只输出正值?

我想到了一些方法,但它们似乎占用了大量的CPU资源,比如制造出比我需要的更多的值,然后对所有正值和
np.random.choice
进行布尔掩码有更好的方法吗?

我在文档中没有看到任何关于这方面的信息:

我发现这并没有产生任何结果: 及


取决于您希望保持的分布的真实程度。如果你只想要正值,它不是一个正态分布,因为你永远不会得到负值


但是,您可以使用
abs(output)
强制正值,其中output是您要查找的
numpy.ndarray
:一个截断的正态连续随机变量

例如,尝试:

>>> from scipy import stats
>>> import numpy as np
>>> np.random.seed(0)
>>> params = (0.00169906712999, 0.00191866845411)
>>> params[0] + stats.truncnorm.rvs(-params[0]/params[1], np.infty, size=10, scale=params[1])
array([ 0.00235414,  0.00310856,  0.00258259,  0.00233789,  0.00185298,
        0.00277454,  0.00190764,  0.00429671,  0.00532165,  0.00169576])
stats.truncnorm.rvs
的前两个参数是截断限制。因为这些是为正态分布计算的(平均值=0 std dev=1),所以我们必须适当地调整参数

我们使用
np.infty
作为范围的上限,因为我们不希望对上限进行任何截断

验证所有输出均为负 让我们看看100000个样本的最小和最大输出:

>>> np.random.seed(0)
>>> np.min(params[0] + stats.truncnorm.rvs(-params[0]/params[1], np.infty, size=100000, scale=params[1]))
1.9136656654716172e-08
>>> np.max(params[0] + stats.truncnorm.rvs(-params[0]/params[1], np.infty, size=10000, scale=params[1]))
0.0088294835649150548

正如你所看到的,最小值从不为负。最大值比平均值高出几个标准偏差。

只要标准偏差(第二个参数,
scale
)大于平均值(第一个参数,
loc
),
.rvs()
将始终有机会输出负数。或半范数,在这种特殊情况下,是否有任何方法可以将此应用于所有分发?这绝对是正常的。谢谢你提供答案的细节。如果没有这些示例,我可能会对实现它感到困惑@ev br如果OP使用平均值为0的分布,则为正常值的一半。但是,看看问题中显示的细节,平均值是非零的
params[0]
。@O.rka提供了一些其他截断分布,例如截断指数分布和截断Gumbel分布。对于其他发行版,可能会产生暴力:生成样本,丢弃超出范围的样本,然后重复,直到生成足够的样本。@John1024 halfnorm with loc=params[0]谢谢。对于非正态分布,我将尝试这个方法。我还想用高通滤波器屏蔽所有的负值。我试图应用它的数据集的范围是0-1,而且非常稀疏。
abs()
的问题是,你实际上是在将正态分布本身折叠起来,这导致它偏离高斯形状。最终,从峰值位于所需平均值且次峰值上升为零的分布中进行采样。
>>> np.random.seed(0)
>>> np.min(params[0] + stats.truncnorm.rvs(-params[0]/params[1], np.infty, size=100000, scale=params[1]))
1.9136656654716172e-08
>>> np.max(params[0] + stats.truncnorm.rvs(-params[0]/params[1], np.infty, size=10000, scale=params[1]))
0.0088294835649150548