Skip to main content

probabilit

A small Python package for Monte Carlo modeling.

  • User friendly API with a modeling language.
  • Built on scipy and numpy.
  • Supports composite distributions (e.g. the mean of a distribution can be a distribution).
  • Supports Quasi-Monte Carlo sampling, e.g. Sobol, Halton and LHS.
  • Supports inducing correlations with Iman-Conover.

You can install it from PyPI.

Modeling

The modeling API lets you create a computational graph, where each node is either a distribution, a constant or a transformation. Once the method .sample() is called on a node, each ancestor node is sampled in turn.

Example 1 - Height. What is the probability that a man is taller than a woman?

>>> from probabilit.modeling import Distribution
>>> male_height = Distribution("norm", loc=176, scale=7.1)
>>> female_height = Distribution("norm", loc=162.5, scale=7.1)
>>> statistic = male_height > female_height
>>> samples = statistic.sample(999, random_state=0)
>>> float(samples.mean())
0.9039...

When statistic is sampled in the code above, the ancestor nodes male_height and female_height are sampled too. In each node, results are stored in the samples_ attribute.

>>> import pandas as pd
>>> pd.Series(male_height.samples_).describe()
count    999.000000
mean     176.096916
std        7.326152
min      153.210671
25%      171.209087
50%      176.044660
75%      180.948085
max      201.216617
dtype: float64

Example 2 - Bird survival. This example illustrates composite distributions, where the argument to one distribution is another distribution. Suppose we have a distribution governing the number of eggs per bird nest for a certain species, and each hatched bird has a survival probability. What is the distribution of the number of birds that survive per nest?

>>> eggs_per_nest = Distribution("poisson", mu=3)
>>> survival_prob = 0.4
>>> survived = Distribution("binom", n=eggs_per_nest, p=survival_prob)
>>> survived.sample(9, random_state=0)  # Sample a few values only
array([2., 1., 1., 2., 2., 2., 2., 0., 0.])

Example 3 - Mutual fund. Suppose we save 1200 units of money per year and that the yearly interest rate has a distribution N(1.11, 0.15). How much money will we have after 20 years?

>>> saved_per_year = 1200
>>> returns = 0
>>> for year in range(20):
...     interest = Distribution("norm", loc=1.11, scale=0.15)
...     returns = returns * interest + saved_per_year
>>> samples = returns.sample(999, random_state=42)
>>> float(samples.mean()), float(samples.std())
(76630.897..., 34507.634...)

Low-level API

The low-level API contains numpy functions for working with random variables. The two most important ones are (1) the nearest_correlation_matrix function and (2) the ImanConover class.

Fixing user-supplied correlation matrices. The function nearest_correlation_matrix can be used to fix user-specified correlation matrices, which are often invalid. Below a user has specified some correlations, but the resulting correlation matrix has a negative eigenvalue and is not positive definite.

>>> import numpy as np
>>> from probabilit.correlation import nearest_correlation_matrix
>>> X = np.array(
...     [
...         [1, 0.9, 0],
...         [0.9, 1, 0.8],
...         [0, 0.8, 1],
...     ],
... )
>>> np.linalg.eigvalsh(X)  # Not a valid correlation matrix
array([-0.20415946,  1.        ,  2.20415946])
>>> nearest_correlation_matrix(X)
array([[1.        , 0.77523696, 0.07905637],
       [0.77523696, 1.        , 0.69097837],
       [0.07905637, 0.69097837, 1.        ]])
>>> np.linalg.eigvalsh(nearest_correlation_matrix(X))
array([1.66...e-06, 9.21470...e-01, 2.07852...e+00])

Inducing correlations on samples. The class ImanConover can be used to induce correlations on uncorrelated variables without changing the marginal distributions. There's no guarantee that we're able to achieve the desired correlation structure, but in practice we often get close.

>>> import scipy as sp
>>> from probabilit.correlation import ImanConover
>>> sampler = sp.stats.qmc.LatinHypercube(d=2, seed=42, scramble=True)
>>> samples = sampler.random(n=100)
>>> X = np.vstack(
...     (sp.stats.triang(0.5).ppf(samples[:, 0]), sp.stats.gamma.ppf(samples[:, 1], a=1))
... ).T

Now we can induce correlations:

>>> float(sp.stats.pearsonr(*X.T).statistic)
0.065898...
>>> correlation_matrix = np.array([[1, 0.3], [0.3, 1]])
>>> transform = ImanConover().set_target(correlation_matrix)
>>> X_transformed = transform(X)
>>> float(sp.stats.pearsonr(*X_transformed.T).statistic)
0.279652...

Metadata

Release files for probabilit 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for probabilit 0.5.0
File Size Uploaded
probabilit-0.5.0.tar.gz 63.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for probabilit 0.5.0
File Interpreter ABI Platform
probabilit-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 115.2 kB

Release files / probabilit-0.5.0.tar.gz

Download URL probabilit-0.5.0.tar.gz
Size 63.8 kB
Tags Source
SHA-256 checksum
How to use checksums
adcde734291e3276647716b2861d40aa8eb2f52172ab8157c3c17484489bf46b
BLAKE2b-256 checksum
How to use checksums
87ea5ac2c3a12b34576df5b85fe025aae027b151168833273a050b3da4785bab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / probabilit-0.5.0-py3-none-any.whl

Download URL probabilit-0.5.0-py3-none-any.whl
Size 51.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0be33d49cb2b21e7a8858bd8e51b5c885a23bb4bcaf78ce5ecae88a9b5650dc6
BLAKE2b-256 checksum
How to use checksums
22be2f6e093df6112bd39de171a53c849a2d7e2f60af5af35c389ff1b0f9619a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

0.5.2

2 release files

This release

0.5.0 This release

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page