scipy.stats.

make_distribution#

scipy.stats.make_distribution(dist)[source]#

Generate a ContinuousDistribution class from a compatible object

The argument may be an instance of rv_continuous or an instance of another class that satisfies the interface described below.

The returned value is a ContinuousDistribution subclass. Like any subclass of ContinuousDistribution, it must be instantiated (i.e. by passing all shape parameters as keyword arguments) before use. Once instantiated, the resulting object will have the same interface as any other instance of ContinuousDistribution; e.g., scipy.stats.Normal.

Note

make_distribution does not work perfectly with all instances of rv_continuous. Known failures include levy_stable and vonmises, and some methods of some distributions will not support array shape parameters.

Parameters:
distrv_continuous

Instance of rv_continuous OR an instance of any class with the following attributes:

__make_distribution_version__str

A string containing the version number of SciPy in which this interface is defined. The preferred interface may change in future SciPy versions, in which case support for an old interface version may be deprecated and eventually removed.

parametersdict

A dictionary describing the parameters of the distribution. Each key is the name of a parameter, and the corresponding value is itself a dictionary with the following items.

endpointstuple

A tuple defining the lower and upper endpoints of the domain of the parameter. Allowable values are floats or the name (string) of another parameter.

inclusivetuple of bool

A tuple specifying whether the endpoints are included within the domain of the parameter.

supporttuple

A tuple defining the lower and upper endpoints of the support of the distribution. Allowable values are floats or the name (string) of a parameter.

The class must also define a pdf method and may define methods logentropy, entropy, median, mode, logpdf, logcdf, cdf, logccdf, ccdf, ilogcdf, icdf, ilogccdf, and iccdf. If defined, these methods must accept the parameters of the distributions as keyword arguments and also accept any positional-only arguments accepted by the corresponding method of ContinuousDistribution. Methods moment_raw, moment_central, moment_standardized may also be defined; if so, they must accept the order of the moment by position, accept all distribution parameters by keyword, and return the raw, central, and standardized moments of the distribution, respectively.

Returns:
CustomDistributionContinuousDistribution

A subclass of ContinuousDistribution corresponding with dist. The initializer requires all shape parameters to be passed as keyword arguments (using the same names as the instance of rv_continuous).

Notes

The documentation of ContinuousDistribution is not rendered. See below for an example of how to instantiate the class (i.e. pass all shape parameters of dist to the initializer as keyword arguments). Documentation of all methods is identical to that of scipy.stats.Normal. Use help on the returned class or its methods for more information.

Examples

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy import stats

Create a ContinuousDistribution from scipy.stats.loguniform.

>>> LogUniform = stats.make_distribution(stats.loguniform)
>>> X = LogUniform(a=1.0, b=3.0)
>>> np.isclose((X + 0.25).median(), stats.loguniform.ppf(0.5, 1, 3, loc=0.25))
np.True_
>>> X.plot()
>>> sample = X.sample(10000, rng=np.random.default_rng())
>>> plt.hist(sample, density=True, bins=30)
>>> plt.legend(('pdf', 'histogram'))
>>> plt.show()
../../_images/scipy-stats-make_distribution-1_00_00.png

Create a custom distribution.

>>> class MyLogUniform:
...     @property
...     def __make_distribution_version__(self):
...         return "1.16.0"
...
...     @property
...     def parameters(self):
...         return {'a': {'endpoints': (0, np.inf),
...                       'inclusive': (False, False)},
...                 'b': {'endpoints': ('a', np.inf),
...                       'inclusive': (False, False)}}
...
...     @property
...     def support(self):
...         return 'a', 'b'
...
...     def pdf(self, x, a, b):
...         return 1 / (x * (np.log(b)- np.log(a)))
>>>
>>> MyLogUniform = stats.make_distribution(MyLogUniform())
>>> Y = MyLogUniform(a=1.0, b=3.0)
>>> np.isclose(Y.cdf(2.), X.cdf(2.))
np.True_