bundles / scipy 1.17.1 / scipy / stats / _distribution_infrastructure / make_distribution
function
scipy.stats._distribution_infrastructure:make_distribution
Signature
def make_distribution ( dist ) Summary
Generate a UnivariateDistribution class from a compatible object
Extended Summary
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 if the input is an instance of rv_continuous or a DiscreteDistribution subclass if the input is an instance of rv_discrete. Like any subclass of UnivariateDistribution, 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 UnivariateDistribution; e.g., scipy.stats.Normal, scipy.stats.Binomial.
Parameters
dist: `rv_continuous`Instance of
rv_continuous, rv_discrete, or an instance of any class with the following attributes:__make_distribution_version__
__make_distribution_version__
parameters
parameters
support
support
The class must also define a
pdfmethod and may define methodslogentropy,entropy,median,mode,logpdf,logcdf,cdf,logccdf,ccdf,ilogcdf,icdf,ilogccdf,iccdf,moment, andsample. If defined, these methods must accept the parameters of the distribution as keyword arguments and also accept any positional-only arguments accepted by the corresponding method of ContinuousDistribution. When multiple parameterizations are defined, these methods must accept all parameters from all parameterizations. Themomentmethod must accept theorderandkindarguments by position or keyword, but may returnNoneif a formula is not available for the arguments; in this case, the infrastructure will fall back to a default implementation. Thesamplemethod must acceptshapeby position or keyword, but contrary to the public method of the same name, the argument it receives will be the full shape of the output array - that is, the shape passed to the public method prepended to the broadcasted shape of random variable parameters.
Returns
CustomDistribution: `UnivariateDistribution`A subclass of UnivariateDistribution corresponding with
dist. The initializer requires all shape parameters to be passed as keyword arguments (using the same names as the instance ofrv_continuous/rv_discrete).
Notes
The documentation of UnivariateDistribution 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.
Array API Standard Support
make_distribution has experimental support for Python Array API Standard compatible backends in addition to NumPy. Please consider testing these features by setting an environment variable SCIPY_ARRAY_API=1 and providing CuPy, PyTorch, JAX, or Dask arrays as array arguments. The following combinations of backend and device (or other capability) are supported.
==================== ==================== ==================== Library CPU GPU ==================== ==================== ==================== NumPy ✅ n/a CuPy n/a ⛔ PyTorch ⛔ ⛔ JAX ⛔ ⛔ Dask ⛔ n/a ==================== ==================== ====================
See
dev-arrayapifor more information.
Examples
import numpy as np import matplotlib.pyplot as plt from scipy import stats from scipy import special✓
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))✓
X.plot()
✗sample = X.sample(10000, rng=np.random.default_rng())
✓plt.hist(sample, density=True, bins=30) plt.legend(('pdf', 'histogram'))✗
plt.show()
✓
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 {'endpoints': ('a', 'b'), 'inclusive': (True, True)} 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.))✓
class MyUniformCube: @property def __make_distribution_version__(self): return "1.16.0" @property def parameters(self): return {"a": (-np.inf, np.inf), "b": {'endpoints':('a', np.inf), 'inclusive':(True, False)}} @property def support(self): def left(*, a, b): return a**3 def right(*, a, b): return b**3 return (left, right) def pdf(self, x, *, a, b): return 1 / (3*(b - a)*np.cbrt(x)**2) def cdf(self, x, *, a, b): return (np.cbrt(x) - a) / (b - a) MyUniformCube = stats.make_distribution(MyUniformCube()) X = MyUniformCube(a=-2, b=2) Y = stats.Uniform(a=-2, b=2)**3✓
X.support()
✗np.isclose(X.cdf(2.1), Y.cdf(2.1))
✓class MyBeta: @property def __make_distribution_version__(self): return "1.16.0" @property def parameters(self): return ({"a": (0, np.inf), "b": (0, np.inf)}, {"mu": (0, 1), "nu": (0, np.inf)}) def process_parameters(self, a=None, b=None, mu=None, nu=None): if a is not None and b is not None: nu = a + b mu = a / nu else: a = mu * nu b = nu - a return dict(a=a, b=b, mu=mu, nu=nu) @property def support(self): return {'endpoints': (0, 1)} def pdf(self, x, a, b, mu, nu): return special._ufuncs._beta_pdf(x, a, b) def cdf(self, x, a, b, mu, nu): return special.betainc(a, b, x) MyBeta = stats.make_distribution(MyBeta()) X = MyBeta(a=2.0, b=2.0) Y = MyBeta(mu=0.5, nu=4.0) np.isclose(X.pdf(0.3), Y.pdf(0.3))✓
Aliases
-
scipy.stats.make_distribution