Skip to main content

An object-oriented approach to defining and combining random variables

Project description

RandCraft

RandCraft is a Python library for object-oriented combination and manipulation of univariate random variables, built on top of the scipy.stats module.

Usage Example

Have you ever wanted to add together random variables but can't be bothered working out an analytical solution? Randcraft makes it simple.

from randcraft import make_normal, make_coin_flip

coin_flip = make_coin_flip()
# <RandomVariable(discrete): mean=0.5, var=0.25>
norm = make_normal(mean=0, std_dev=0.2)
# <RandomVariable(normal): mean=0.0, var=0.04>
combined = coin_flip + norm 
# <RandomVariable(mixture): mean=0.5, var=0.29>
combined.sample_one()
# 0.8678903828104276
combined.plot()

Double normal

Features

  • Object-oriented random variables: Wrap and combine distributions as Python objects.
  • Distribution composition: Add, multiply, and transform random variables.
  • Sampling and statistics: Easily sample from composed distributions and compute statistics.
  • Extensible: Supports custom distributions via subclassing.
  • Integration with scipy.stats: Use any frozen continuous distribution from scipy stats

Supported Distributions

RandCraft currently supports the following distributions:

  • Normal, Uniform, Beta, Gamma, Lognormal + any other parametric continuous distribution from scipy.stats
  • Discrete
  • DiracDelta
  • Gaussian kde distribution from provided observations
  • Mixture distributions
  • Anonymous distribution functions based on a provided sampler function

Distributions can all be combined arbitrarily with addition and subtraction. The library will simplify the new distribution analytically where possible, and use numerical approaches otherwise.

You can also extend RandCraft with your own custom distributions.

Installation

pip install randcraft

API Overview

  • make_normal, make_uniform ...etc: Create a random variable
  • Addition subtraction with constants or other RVs: +, -
  • Division by constant to scale RV values
  • .sample_numpy(size): Draw samples
  • .get_mean(), .get_variance(): Get statistics
  • .cdf(x): Evaluate cdf at points
  • .ppf(x): Evaluate inverse of cdf at points
  • .plot(): Take a look at your distribution

More Examples

Combining dice rolls

from randcraft.constructors import make_die_roll

die = make_die_roll(sides=6)
# <RandomVariable(discrete): mean=3.5, var=2.92>
three_dice = die.multi_sample(3)
# <RandomVariable(discrete): mean=10.5, var=8.75>
three_dice.cdf(10.0)
# 0.5
three_dice.ppf(0.5)
# 10.0

Using arbitrary parametric continuous distribution from scipy.stats

from scipy.stats import uniform
from randcraft.constructors import make_scipy

rv = make_scipy(uniform, loc=1, scale=2)
# <RandomVariable(scipy-uniform): mean=2.0, var=0.333>
b = rv.scale(2.0)
# <RandomVariable(scipy-uniform): mean=4.0, var=1.33>

Kernel density estimation and combination

You have observations of two independent random variables. You want to use kernal density estimation to create continuous random variables for each and then add them together.

import numpy as np
from randcraft.observations import make_gaussian_kde

observations_a = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
observations_b = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0])
rv_a = make_gaussian_kde(observations=observations_a, bw_method=0.1)
# <RandomVariable(multi): mean=3.0, var=2.42>
rv_b = make_gaussian_kde(observations=observations_b)
# <RandomVariable(multi): mean=0.5, var=0.676>
rv_joined = rv_a + rv_b
# <RandomVariable(multi): mean=3.5, var=3.1>

Uses gaussian_kde by scipy.stats under the hood. You also have the option to pass arguments for gaussian_kde, or provide your own kernel as a RandomVariable.

The central limit theorem

from randcraft import make_uniform

rv = make_uniform(low=0, high=1)
# <RandomVariable(scipy-uniform): mean=0.5, var=0.0833>
rv_sample_mean = rv.multi_sample(n=30)/30
# <RandomVariable(multi): mean=0.5, var=0.00278>
rv_sample_mean.plot()

CentralLimit

Mixing continuous and discrete variables

You have observations of two independent random variables. You want to use kernal density estimation to create continuous random variables for each and then add them together.

from randcraft.constructors import make_normal, make_uniform, make_discrete
from randcraft.misc import mix_rvs

rv1 = make_normal(mean=0, std_dev=1)
# <RandomVariable(scipy-norm): mean=0.0, var=1.0>
rv2 = make_uniform(low=-1, high=1)
# <RandomVariable(scipy-uniform): mean=-0.0, var=0.333>
combined = rv1 + rv2
# <RandomVariable(multi): mean=0.0, var=1.33>
discrete = make_discrete(values=[1, 2, 3])
# <RandomVariable(discrete): mean=2.0, var=0.667>

# Make a new rv which has a random chance of drawing from one of the other 4 rvs
mixed = mix_rvs([rv1, rv2, combined, discrete])
# <RandomVariable(mixture): mean=0.5, var=1.58>
mixed.plot()

Mixture

Extending RandCraft

You can create custom random variable classes by subclassing the base RV class and implementing required methods.

Known limitations

The library is designed to work with univariate random variables only. Multi-dimensional rvs or correlations etc are not supported.

License

MIT License

Acknowledgements

Built on scipy.stats.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

randcraft-0.1.10.tar.gz (243.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

randcraft-0.1.10-py3-none-any.whl (25.3 kB view details)

Uploaded Python 3

File details

Details for the file randcraft-0.1.10.tar.gz.

File metadata

  • Download URL: randcraft-0.1.10.tar.gz
  • Upload date:
  • Size: 243.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for randcraft-0.1.10.tar.gz
Algorithm Hash digest
SHA256 a94a7fda5c55efcf532e60f8e4f2c8fb3526387615152a1a58ebf4f74948c552
MD5 75d4ad9deb01c0e4b39461783a3480f0
BLAKE2b-256 47fc5b2f8e8214ec2add9d1a4f24e5abff118324ade930aa29c750e3e1e59269

See more details on using hashes here.

Provenance

The following attestation bundles were made for randcraft-0.1.10.tar.gz:

Publisher: publish.yml on RobbieKiwi/RandCraft

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file randcraft-0.1.10-py3-none-any.whl.

File metadata

  • Download URL: randcraft-0.1.10-py3-none-any.whl
  • Upload date:
  • Size: 25.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for randcraft-0.1.10-py3-none-any.whl
Algorithm Hash digest
SHA256 44e60d9a57b030e5dfd29b6a095bbd130beb8b65ffc08fdf464a3b35ba9a42ba
MD5 ad79000164f388274a68dd3c7f99beeb
BLAKE2b-256 d5685efcf14f4da940eca84c65d21a356744edb6beb5ecb3632ab694ab4203e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for randcraft-0.1.10-py3-none-any.whl:

Publisher: publish.yml on RobbieKiwi/RandCraft

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page