Written by Peter Rosenmai on 27 Feb 2021.

Below is a Python function to convert unconventional parameterizations of the lognormal distribution
into the standard parameterization. It takes the

(a) mean and median or

(b) mean and mode or

(c) median and mode

of a lognormal distribution and returns the mean and standard deviation of its underlying normal distribution.

Often when working on simulations, colleagues give me rough sketches of probability distribution functions that they want me to use for random sampling. These typically resemble lognormal distributions, so I find the function I provide here to be quite useful.

import numpy as np

def get_lognormal_mu_sigma(logn_mean=None, logn_median=None, logn_mode=None):

"""Returns the mean (mu) and the standard deviation (sigma) of the normal

distribution that defines a lognormal distribution with the supplied

parameters.

For example, random sampling from a lognormal distribution with a median of

10 and a mean of 20 is equivalent to random sampling from a normal distribution

with a mean of mu and a standard deviation of sigma, where

mu, sigma = get_lognormal_mu_sigma(20, 10)

Args:

logn_mean (float, optional): The mean of the lognormal distribution.

Defaults to None.

logn_median (float, optional): The median of the lognormal distribution.

Defaults to None.

logn_mode (float, optional): The mode of the lognormal distribution.

Defaults to None.

Returns:

(float, float): The mean (mu) and the standard deviation (sigma) of the

underlying normal distribution.

Raises:

ValueError: If the supplied parameters are mathematically invalid, such

as when the supplied mean is less than the supplied median.

"""

if sum(param is not None for param in [logn_mean, logn_median, logn_mode]) != 2:

raise ValueError("Exactly two parameters must be supplied.")

if logn_mean and logn_median: # Mean and median.

if logn_mean < logn_median:

raise ValueError("The mean cannot be less than the median.")

mu = np.log(logn_median)

sigma = np.sqrt(2 * (np.log(logn_mean) - np.log(logn_median)))

elif logn_mean and logn_mode: # Mean and mode.

if logn_mean < logn_mode:

raise ValueError("The mean cannot be less than the mode.")

mu = (np.log(logn_mode) + 2 * np.log(logn_mean)) / 3

sigma = np.sqrt(2 * (np.log(logn_mean) - np.log(logn_mode)) / 3)

else: # Median and mode.

if logn_median < logn_mode:

raise ValueError("The median cannot be less than the mode.")

mu = np.log(logn_median)

sigma = np.sqrt(np.log(logn_median) - np.log(logn_mode))

return mu, sigma

def get_lognormal_mu_sigma(logn_mean=None, logn_median=None, logn_mode=None):

"""Returns the mean (mu) and the standard deviation (sigma) of the normal

distribution that defines a lognormal distribution with the supplied

parameters.

For example, random sampling from a lognormal distribution with a median of

10 and a mean of 20 is equivalent to random sampling from a normal distribution

with a mean of mu and a standard deviation of sigma, where

mu, sigma = get_lognormal_mu_sigma(20, 10)

Args:

logn_mean (float, optional): The mean of the lognormal distribution.

Defaults to None.

logn_median (float, optional): The median of the lognormal distribution.

Defaults to None.

logn_mode (float, optional): The mode of the lognormal distribution.

Defaults to None.

Returns:

(float, float): The mean (mu) and the standard deviation (sigma) of the

underlying normal distribution.

Raises:

ValueError: If the supplied parameters are mathematically invalid, such

as when the supplied mean is less than the supplied median.

"""

if sum(param is not None for param in [logn_mean, logn_median, logn_mode]) != 2:

raise ValueError("Exactly two parameters must be supplied.")

if logn_mean and logn_median: # Mean and median.

if logn_mean < logn_median:

raise ValueError("The mean cannot be less than the median.")

mu = np.log(logn_median)

sigma = np.sqrt(2 * (np.log(logn_mean) - np.log(logn_median)))

elif logn_mean and logn_mode: # Mean and mode.

if logn_mean < logn_mode:

raise ValueError("The mean cannot be less than the mode.")

mu = (np.log(logn_mode) + 2 * np.log(logn_mean)) / 3

sigma = np.sqrt(2 * (np.log(logn_mean) - np.log(logn_mode)) / 3)

else: # Median and mode.

if logn_median < logn_mode:

raise ValueError("The median cannot be less than the mode.")

mu = np.log(logn_median)

sigma = np.sqrt(np.log(logn_median) - np.log(logn_mode))

return mu, sigma