Apply kurtosis to a distribution in python
distribution, python, scipy, statistics
Solution
If you have mean, standard deviation, skew and kurtosis, then you can build an approximately normal distribution with those moments using Gram-Charlier expansion.
I looked into this some time ago, scipy.stats had a function that was wrong and was removed.
I don't remember what the status of this is, since it was a long time ago that I put this in the statsmodels sandbox http://statsmodels.sourceforge.net/devel/generated/statsmodels.sandbox.distributions.extras.pdf_mvsk.html#statsmodels.sandbox.distributions.extras.pdf_mvsk
Problem
I have a dataset which is in the format of frequency, direction, normalised power spectral density, spread, skewness, kurtosis I am able to visualise the distribution of a specific record using the code from the top answer in skew normal distribution in scipy but I am not sure how to apply a kurtosis value to a distribution? ``` from scipy import linspace from scipy import pi,sqrt,exp from scipy.special import erf from pylab import plot,show def pdf(factor, x): return (100*factor)/sqrt(2*pi) * exp(-x**2/2) def cdf(x): return (1 + erf(x/sqrt(2))) / 2 def skew(x,e=0,w=1,a=0, norm_psd=1): t = (x-e) / w return 2 / w * pdf(norm_psd, t) * cdf(a*t) n = 540 e = 341.9 # direction w = 59.3 # spread a = 3.3 # skew k = 4.27 # kurtosis n_psd = 0.5 # normalised power spectral density x = linspace(-90, 450, n) p = skew(x, e, w, a, n_psd) print max(p) plot(x,p) show() ``` Edit: I removed skew normal from my title as I don't think it is actually possible to apply a kurtosis value to the above distribution, I think a different distribution is necessary, as direction is involved a distribution from circular statistics may be more appropriate? Thanks to the answer below I can apply kurtosis using the pdf_mvsk function demonstrated in the code below, unfortunately my skew values cause a negative y value, but the answer satisfies my question. ``` import numpy as np import matplotlib.pyplot as plt import statsmodels.sandbox.distributions.extras as extras pdffunc = extras.pdf_mvsk([341.9, 59.3, 3.3, 4.27]) range = np.arange(0, 360, 0.1) plt.plot(range, pdffunc(range)) plt.show() ```