20

random.gauss(mu, sigma)

Above is a function allowing to randomly draw a number from a normal distribution with a given mean and variance. But how can we draw values from a normal distribution defined by more than only the two first moments?

something like:

random.gauss(mu, sigma, skew, kurtosis)

Saullo G. P. Castro
  • 56,802
  • 26
  • 179
  • 234
Remi.b
  • 17,389
  • 28
  • 87
  • 168
  • 6
    Any normal distribution has skew 0 and kurtosis 0. Use a different family of distributions. – Bennett Brown Oct 26 '13 at 09:57
  • 2
    Beware, there are several ways to define the calculation for skew and kurtosis. Moments are not equivalent to mean, variance, skew, and kurtosis, though they have the same gist. – Bennett Brown Oct 26 '13 at 10:02
  • 3
    Also, the moments do not specify a unique distribution. See [this similar question but asking about R: http://stackoverflow.com/questions/4807398/how-to-generate-distributions-given-mean-sd-skew-and-kurtosis-in-r – Bennett Brown Oct 26 '13 at 10:03
  • I would suggest to have a look at [This](https://www.hackerearth.com/blog/developers/descriptive-statistics-python-numpy/) – champion-runner Oct 15 '19 at 17:48

2 Answers2

10

How about using scipy? You can pick the distribution you want from continuous distributions in the scipy.stats library.

The generalized gamma function has non-zero skew and kurtosis, but you'll have a little work to do to figure out what parameters to use to specify the distribution to get a particular mean, variance, skew and kurtosis. Here's some code to get you started.

import scipy.stats
import matplotlib.pyplot as plt
distribution = scipy.stats.norm(loc=100,scale=5)
sample = distribution.rvs(size=10000)
plt.hist(sample)
plt.show()
print distribution.stats('mvsk')

This displays a histogram of a 10,000 element sample from a normal distribution with mean 100 and variance 25, and prints the distribution's statistics:

(array(100.0), array(25.0), array(0.0), array(0.0))

Replacing the normal distribution with the generalized gamma distribution,

distribution = scipy.stats.gengamma(100, 70, loc=50, scale=10)

you get the statistics [mean, variance, skew, kurtosis] (array(60.67925117494595), array(0.00023388203873597746), array(-0.09588807605341435), array(-0.028177799805207737)).

Bennett Brown
  • 5,234
  • 1
  • 27
  • 35
5

Try to use this:

http://statsmodels.sourceforge.net/devel/generated/statsmodels.sandbox.distributions.extras.pdf_mvsk.html#statsmodels.sandbox.distributions.extras.pdf_mvsk

Return the Gaussian expanded pdf function given the list of 1st, 2nd moment and skew and Fisher (excess) kurtosis.

Parameters : mvsk : list of mu, mc2, skew, kurt

Looks good to me. There's a link to the source on that page.

Oh, and here's the other StackOverflow question that pointed me there: Apply kurtosis to a distribution in python

Community
  • 1
  • 1
sdanzig
  • 4,510
  • 1
  • 23
  • 27
  • 3
    Is there a convenient way to draw values from this distribution, rather than just compute the density? – kuzzooroo Dec 05 '13 at 00:11
  • 1
    what is meant by mc2 here? i anticipate variance, but just want to be sure. – jason m Mar 14 '16 at 14:05
  • "*In the Gram-Charlier distribution, it is possible that the density becomes negative. This is when the deviation from the normal distribution is too large.*" So far I found this method the best in respect to accepting all 4 moments, and the worst in convergence. – Yahya Jun 24 '22 at 13:27