scipy.stats has every distribution and statistical test. statsmodels adds regression diagnostics, time series models (ARIMA, ADF), and proper statistical inference with confidence intervals — what sklearn deliberately leaves out.
| Task | scipy.stats | statsmodels |
|---|---|---|
| Compare two groups | ttest_ind, mannwhitneyu | — |
| Normality | shapiro, normaltest | — |
| Regression | — | OLS with summary() |
| Time series | — | ARIMA, adfuller, acf |
| Distributions | norm, beta, gamma, etc. | — |
Ten p-values, eight of them below 0.05. Bonferroni keeps 2 as significant; the Benjamini–Hochberg procedure keeps 6, controlling the expected share of false discoveries instead of the chance of any. statsmodels’ multipletests does both; which one is right depends on whether a single false positive is costly or a few are acceptable.
- Corrections apply to the family of tests you actually ran, including the ones you did not report.
- Benjamini–Hochberg assumes independent or positively dependent tests; under other dependence use Benjamini–Yekutieli.
- A non-significant result after correction is not evidence of no effect.
p = np.array([0.001, 0.004, 0.008, 0.012, 0.02, 0.03, 0.04, 0.045, 0.2, 0.5]) m = len(p) bonferroni = (p < 0.05 / m).sum() order = np.sort(p) passed = order <= 0.05 * np.arange(1, m + 1) / m # Benjamini-Hochberg step-up bh = (np.max(np.nonzero(passed)) + 1) if passed.any() else 0
Assumes import numpy as np and import pandas as pd (and SciPy where imported). Each snippet simulates or makes up its own data, as the comments say.
The same idea with a library
# scipy.stats — statistical tests from scipy.stats import ( ttest_ind, ttest_rel, mannwhitneyu, ks_2samp, shapiro, spearmanr ) # Two-sample t-test t_stat, p_val = ttest_ind(group_a, group_b) # Normality check stat, p = shapiro(data) # statsmodels — regression with full diagnostics import statsmodels.api as sm X_sm = sm.add_constant(X) model = sm.OLS(y, X_sm).fit() print(model.summary()) # R², coefficients, p-values, CI # Time series — ADF stationarity test from statsmodels.tsa.stattools import adfuller result = adfuller(series) print(f"ADF Stat: {result[0]:.3f}, p: {result[1]:.4f}")
- Y. Benjamini & Y. Hochberg, “Controlling the False Discovery Rate: A Practical and Powerful Approach to Multiple Testing”, Journal of the Royal Statistical Society B 57(1), 1995
- S. Holm, “A Simple Sequentially Rejective Multiple Test Procedure”, Scandinavian Journal of Statistics 6(2), 1979
- S. Seabold & J. Perktold, “Statsmodels: Econometric and Statistical Modeling with Python”, Proceedings of the 9th Python in Science Conference, 2010
- P. Virtanen et al., “SciPy 1.0: Fundamental Algorithms for Scientific Computing in Python”, Nature Methods 17, 2020
Last reviewed October 2026 · How this site checks its content · Report a mistake