Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Python libraries for doing statistics

see draft here: https://docs.google.com/document/d/1a-Ohl3hs7w8AiOr85PxW0DZP1ofFK02sk55IEw0zQPE/edit?tab=t.0

Click here to run the notebook interactively, so you can play with the code examples.

Notebook setup


[notice] A new release of pip is available: 25.2 -> 25.3
[notice] To update, run: pip install --upgrade pip
Note: you may need to restart the kernel to use updated packages.
<Figure size 640x480 with 0 Axes>

Introduction

IQ scores sample

Consider the following dataset, which consists of IQ scores of 30 students who took a “smart drug” ☕. The IQ scores are recorded in the following list.

Statistics procedures as readable code (ministats)

Generating sampling distributions

def gen_sampling_dist(rv, estfunc, n, N=10000): """ Simulate `N` samples of size `n` from the random variable `rv` to generate the sampling distribution of the estimator `estfunc`. """ estimates = [] for j in range(N): sample = rv.rvs(n) estimate = estfunc(sample) estimates.append(estimate) return estimates

One-sample t-test for the mean

def ttest_mean(sample, mu0, alt="two-sided"): """ T-test to detect mean deviation from a population with known mean `mu0`. """ assert alt in ["greater", "less", "two-sided"] obsmean = np.mean(sample) n = len(sample) std = np.std(sample, ddof=1) sehat = std / np.sqrt(n) obst = (obsmean - mu0) / sehat rvT = tdist(df=n-1) pvalue = tailprobs(rvT, obst, alt=alt) return pvalue
np.float64(0.01792942680682752)

Generating bootstrap distributions

def gen_boot_dist(sample, estfunc, B=5000): """ Generate estimates from the sampling distribution of the estimator `estfunc` based on `B` bootstrap samples (sampling with replacement) from `sample`. """ n = len(sample) bestimates = [] for j in range(B): bsample = np.random.choice(sample, n, replace=True) bestimate = estfunc(bsample) bestimates.append(bestimate) return bestimates
<Figure size 700x200 with 1 Axes>

The permutation test for comparing two groups

def permutation_test_dmeans(xsample, ysample, P=10000): """ Compute the p-value of the observed difference between means `dmeans(xsample,ysample)` under the null hypothesis where the group membership is randomized. """ # 1. Compute the observed difference between means obsdhat = dmeans(xsample, ysample) # 2. Get sampling dist. of `dmeans` under H0 pdhats = [] for i in range(0, P): rsx, rsy = resample_under_H0(xsample, ysample) pdhat = dmeans(rsx, rsy) pdhats.append(pdhat) # 3. Compute the p-value tails = tailvalues(pdhats, obsdhat) pvalue = len(tails) / len(pdhats) return pvalue
def resample_under_H0(xsample, ysample): """ Generate new samples from a random permutation of the values in the samples `xsample` and `ysample`. """ values = np.concatenate((xsample, ysample)) shuffled_values = np.random.permutation(values) xresample = shuffled_values[0:len(xsample)] yresample = shuffled_values[len(xsample):] return xresample, yresample
0.0098

See the ministats library for more examples of Python functions that implement the statistical procedures in STATS 101.

In the past, students first contact with statistics was presented as a bunch of procedures without explanation, and students were supposed to memorize when to use which “recipe”. Statistics instructors always had to “skip the details” because it’s super complicated to explain all the details (probability models, sampling distributions, p-value calculations, etc.).

Now that we have Python on our side, we don’t have to water-down the material, but can instead show all the detailed calculations for statistical tests, as easy-to-understand Python source code, which makes it much much easier to understand what is going on. Currently, the ministats library contains about 400 lines of code. With a little bit of Python knowledge, you can read the source code and understand all of statistics.

Conclusion