# Is there a way to generate a lognormal distribution from a pre-defined normal distribution?

## Question:

I have the code which generates a normal distribution as a pdf, centered at the mean 400, with st

```
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats
muPrev, sigmaPrev = 400, 40.
a = np.random.normal(muPrev, sigmaPrev, 100000)
count, bins, ignored = plt.hist(a, 1000, density=True)
plt.plot(bins, 1/(sigmaPrev * np.sqrt(2 * np.pi)) *
np.exp( - (bins - muPrev)**2 / (2 * sigmaPrev**2) ),linewidth=3, color='r')
```

and I can visualise it. But what if I wanted to convert this into a lognormal distribution? So that I now get values of mu and sigma that correspond to this as a log distribution?

## Answers:

You could directly generate samples for a lognormal distribution with https://numpy.org/doc/stable/reference/random/generated/numpy.random.lognormal.html, alternatively:

```
log_norm = np.exp(a)
```

Note that if you want to generate the lognormal directly you need to calculate the appropriate mean and variance https://en.wikipedia.org/wiki/Log-normal_distribution

To give a more complete answer, here’s some code that draws a figure with two plots: one shows your existing Gaussian draws and another for log-normal draws. I keep the first and second moments the same (i.e. mean and variance) by setting the log-normal mu=`log(mu)`

and sigma=`sd/mu`

.

```
import numpy as np
import scipy.stats as sps
import matplotlib.pyplot as plt
mu, sd = 400, 40
n = 100_000
# draw samples from distributions
a = np.random.normal(mu, sd, n)
b = np.random.lognormal(np.log(mu), sd / mu, n)
# use Scipy for analytical PDFs
d1 = sps.norm(mu, sd)
# warning: scipy parameterises its distributions very strangely
d2 = sps.lognorm(sd / mu, scale=mu)
# bins to use for histogram and x for PDFs
lo, hi = np.min([a, b]), np.max([a, b])
dx = (hi - lo) * 0.06
bins = np.linspace(lo, hi, 101)
x = np.linspace(lo - dx, hi + dx, 501)
# draw figure
fig, [ax1, ax2] = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(8, 5))
ax1.set_title("Normal draws")
ax1.set_xlim(lo - dx, hi + dx)
ax1.hist(a, bins, density=True, alpha=0.5)
ax1.plot(x, d1.pdf(x))
ax1.plot(x, d2.pdf(x), '--')
ax2.set_title("Log-Normal draws")
ax2.hist(b, bins, density=True, alpha=0.5, label="Binned density")
ax2.plot(x, d1.pdf(x), '--', label="Normal PDF")
ax2.plot(x, d2.pdf(x), label="Log-Normal PDF")
ax2.legend()
fig.supylabel("Density")
```

which produces the following output:

Because the distributions are so close here, I’ve included dashed lines to show the other distribution for easier comparison. Note that the log-normal distribution will always be slightly right-skewed, more so as the variance increases.

What is posted by @SamMason is not correct. It is somewhat working because your mean and sd are relative large.

Ok, here is what would be correct way to get parameters of the Log-Normal distribution.

You have predefined values of mean (corresponding to your Gaussian mean) and sd (again, your Gaussian sd).

Mean=exp(μ+σ^{2}/2)

Var =(exp(σ^{2}) – 1)(exp(2μ+σ^{2}))

Here μ and σ are log-normal (NOT gaussian) parameter. You have to find them.

- Compute mean from your Gaussian mean (ok, that one is easy, they are equal)
- Compute variance from your Gaussian sd (square)
- Using formulas above solve two non-linear equations system and get your μ and σ
- Plug μ and σ into your sampling routine and draw samples

UPDATE

Mean^{2}=exp(2μ+σ^{2})

Var/Mean^{2} = (exp(σ^{2}) – 1)

So here is your σ. To be more elaborate

Sd^{2}/Mean^{2} = exp(σ^{2}) – 1

exp(σ^{2}) = 1 + Sd^{2}/Mean^{2}

σ^{2} = ln(1 + Sd^{2}/Mean^{2})

From first equation now you could get μ

2μ+σ^{2} = ln(Mean^{2})

2μ=ln(Mean^{2}) – σ^{2} = ln(Mean^{2}) – ln(1 + Sd^{2}/Mean^{2}) = ln((Mean^{2})/(1 + Sd^{2}/Mean^{2}))

Please, check the math, but this is the way to get PRECISE log-normal μ,σ parameters to match desired Mean and Sd.

@SamMason approximation works, I believe, only if in the expression for

σ^{2} = ln(1 + Sd^{2}/Mean^{2})

one have second term much larger than 1. THen you could drop 1 and have log of ratios.

UPDATE II

2μ=ln((Mean^{2})/(1 + Sd^{2}/Mean^{2})) = ln(Mean^{4}/(Mean^{2} + Sd^{2}))

μ=1/2 ln(Mean^{4}/(Mean^{2} + Sd^{2}))=ln(Mean^{2}/Sqrt(Mean^{2} + Sd^{2}))