I am generating a random log-normal distribution using the inbuilt function. Is it possible to specify a range for a given mean
and sigma
? For instance, I want a random distribution between 0
and 0.5
with mean=0.2, sigma=0.5
?
import numpy as np
r=np.random.lognormal(mean=0.2, sigma=0.5, size=(3,3))
print([r])
CodePudding user response:
Not directly, but you can generate more points and filter those that are outside your parameters. With the values you provided, however, there will be very few such points:
np.random.seed(0)
z = np.random.lognormal(mean=0.2, sigma=0.5, size=10_000)
>>> np.sum(z < 0.5) / len(z)
0.0346
As a side note, please know that the parameters mean
and sigma
of np.random.lognormal()
refer to the underlying normal distribution, not to the mean
and std
of the log-normal points:
np.random.seed(0)
z = np.random.lognormal(mean=0.2, sigma=0.5, size=1000)
y = np.log(y)
>>> np.mean(z), np.std(z)
(1.3886515119063163, 0.7414709414626542)
>>> np.mean(y), np.std(y)
(0.2018986489272414, 0.5034218384643446)
All that said, if you really want what you asked for, you could do:
shape = 3, 3
zmin, zmax = 0, 0.5
n = np.prod(shape)
zc = np.array([])
while True:
z = np.random.lognormal(mean=0.2, sigma=0.5, size=n * 100)
z = z[(zmin <= z) & (z < zmax)]
z = np.r_[zc, z]
if len(z) >= n:
break
r = z[:n].reshape(shape)
>>> r
array([[0.34078793, 0.45366409, 0.40183988],
[0.43387773, 0.46387512, 0.30535007],
[0.44248787, 0.32316698, 0.48600577]])
Note, however, that the loop above (which in this case is done on average just once), may run forever if your bounds specify an empty space.