将numpy.random.lognormal限制为给定范围,Python

问题描述 投票:-1回答:3

我正在尝试使用适合年龄数据集的对数正态分布对随机数进行采样。

Age_abscess = numpy.random.lognormal(mean=numpy.log(29.9090909),
              sigma=numpy.log(11.6574484),size=None)

我有时会得到^ 23和小于1的曲调的答案。鉴于我希望这些是年龄,有没有办法将绘制限制在0到100之间?

编辑:经过一番头脑风暴,我想出了:

def lognormal(mean,sigma):
    age = numpy.random.lognormal(mean=numpy.log(mean),sigma=numpy.log(sigma),size=None)
    if 0>= age <= 100:
    age=age
return age

但是,这只会运行一次,所以我必须弄清楚如何循环它直到它满足条件。如果我找到答案,可能会在之前要求更新。

python numpy random
3个回答
0
投票

看起来你正在寻找截断的对数正态分布。 Numpy没有,但你可以找到其他自定义实现,如this one

您拥有的另一个选择是丢弃您的绘图并重复它,如果您的年龄条件不满足!

编辑:如果你想删除你不想要的值,你只需要在你的代码中替换for with:

编辑2:正如kevinkayaks指出的那样,你需要创建一个无限循环并在你的条件满足后中断!

def lognormal(mean,sigma):
    while True:
        age = numpy.random.lognormal(mean=numpy.log(mean),sigma=numpy.log(sigma),size=None)
        if age>=0 and age <= 100:
            break
    return age

1
投票
def lognormal(mean,sigma):
    while True:
        age = np.random.lognormal(mean=np.log(mean),sigma=np.log(sigma),size=None)
        if age >= 0 and age <= 100:
            break
    return age

接受的答案不应该奏效。也许我很困惑


0
投票

以上答案仅适用于单个值。如果您想要一个在该范围内的矢量值,您可以无限循环,直到获得一系列神奇地适合您的范围的值,或者您可以通过从基础分布中重新绘制样本来替换范围之外的值(替换例外)。

i = 0
while True:
   # for first iteration, make an initial vector of random values
   if i == 0:
       V = np.round(np.random.lognormal(mu, sigma, 1000),2)

   #Make binary vectors for those values that are out of range and in range
   V_outRange = (V > 100) + 0.
   V_good = (V < 100) + 0.

   #keep the values in range
   V_ok = np.multiply(V, V_good)

   #Resample values that are out of range
   V_next = np.round(np.multiply(V_outRange, np.random.lognormal(mu, sigma, 1000)),2)

   #Re-combine previous in-range values with newly sampled values
   V = V_ok + V_next

   #check to see if all values are in range, if not re-loop
   if (np.count_nonzero(V > 100)) == 0:
       break

   i += 1
© www.soinside.com 2019 - 2024. All rights reserved.