1

I am given the log10 mean and log10 standard deviation of a log-normal distribution. I want to get a random number from this log-normal distribution.

Can this be accomplished with numpy.random.lognormal, even though that function's inputs are the mean and standard of the underlying normal distribution (I do not have that)?

Also, will the random number that I get back from the function be log10, natural log, or regular?

quantumflash
  • 691
  • 2
  • 5
  • 16
  • Ok, so you have a the distribution of a random variable (let's call it `X`) that is log-normally distributed. You have the log base 10 of the values for the mean and standard deviation of `X`: `log10(mu)` and `log10(sigma)`? Given these, you want to draw more numbers from the same distribution as `X`? – pault Dec 28 '17 at 22:51
  • Sorry @pault I meant that I have mu and sigma of log10(X), where X is a log-normally distributed random variable. As an example, suppose the underlying physical quantity is mass and that it is log-normally distributed. Instead of being given the log-normal mu and sigma of mass, I am given the log-normal mu and sigma of log10(mass). What function in numpy/scipy can I use to give me a log-normal random value of either mass or log10(mass), given that I have mu and sigma of log10(mass)? – quantumflash Dec 28 '17 at 23:49
  • This is not really a programming question and would be better suited at https://math.stackexchange.com/. Try posting there. Once you figure out the math behind it, you can try to ask how to implement the solution. – pault Dec 29 '17 at 01:22

1 Answers1

5

Wikipedia says that the parameters of lognormal distribution are expressed in terms of underlying normal distribution thus:

lognormal_mean = np.exp(normal_mean + normal_std**2 / 2)
lognormal_std = np.sqrt(np.exp(normal_std**2) - 1) * np.exp(normal_mean + normal_std**2 / 2)

With a bit of algebra these can be reversed:

normal_std = np.sqrt(np.log(1 + (lognormal_std/lognormal_mean)**2))
normal_mean = np.log(lognormal_mean) - normal_std**2 / 2

And then you can use those to generate a sample. Here is an example:

lognormal_mean = 3
lognormal_std = 5
normal_std = np.sqrt(np.log(1 + (lognormal_std/lognormal_mean)**2))
normal_mean = np.log(lognormal_mean) - normal_std**2 / 2
sample = np.random.lognormal(normal_mean, normal_std, size=10000000)
print(sample.mean(), sample.std())

In a trial run, the output was 3.00126241708, 4.99737569477 - in agreement with the parameters 3, 5.

The "log" in "lognormal" always stands for natural logarithm (base e), so this is what you will get.

Finally, if your input data is log10(lognormal_mean) and log10(lognormal_std) then the first step would be

lognormal_mean = 10**log10_lognormal_mean_
lognormal_std = 10**log10_lognormal_std

I would also check the source to find if they use the ambiguous phrase "log10 mean" to mean "log10 of mean" or "mean of log10". If it was "mean of log10" then you don't need anything above; you already have the parameters of underlying normal distribution, they just need to be multiplied by log(10) to convert from log10 to natural.

  • Cool thanks this is very helpful! Indeed the source means "mean of log10", not "log10 mean" -- sorry for any confusion. – quantumflash Dec 29 '17 at 18:28