Release 0.15.0#
Release summary#
This note covers all changes merged into main between the v0.15.0.dev0
tag (2023-05-05) and the current development head (2026-07-22). It is a
working draft assembled directly from the git history rather than a final,
polished release announcement, and it does not yet follow the format of
previous versionX.Y.rst release notes.
statsmodels is using github to store the updated documentation. Two versions are available:
Stable, the latest release
Development, the latest build of the main branch
Warning
API stability is not guaranteed for new features, although even in this case changes will be made in a backwards compatible way if possible. The stability of a new feature depends on how much time it was already in statsmodels main and how much usage it has already seen. If there are specific known problems or limitations, then they are mentioned in the docstrings.
Release statistics#
Pull requests merged: 355
Non-merge commits: 953
Contributors (by git log author, unique names): 122
Time span: 2023-05-05 through 2026-07-22
The Highlights#
SPEC-007: consistent use of rng for randomness#
statsmodels is standardizing on a single rng keyword for supplying
entropy (an integer seed, an array of integers, a NumPy Generator, or a
RandomState) wherever a model, estimator, or plotting function needs
randomness, in line with the community’s SPEC 007 convention. The older
random_state and seed keywords are deprecated in favor of rng.
Passing the old keyword still works and is transparently remapped to
rng, but it now raises a FutureWarning and will be removed in a
future release. This is one of the largest cross-cutting changes in this
release and touches, among others:
State space models (
MLEResults.simulate, simulation smoothers, impulse response simulation):random_state->rng.Distributions: copulas,
BernsteinDistribution,DiscretizedCount,MixtureDistribution, and relatedrvs-style methods:random_state->rng.MixedLM,nonlinls, GAM cross-validation, and severalsandboxdistributions:random_state->rng.Nonparametric estimation (
KDEMultivariate,KDEMultivariateConditional,KernelReg,KernelCensoredReg,TestRegCoefC/TestRegCoefD):seed->rng.VAR/SVAR/IRF simulation and Monte Carlo error bands (
varsim,VAR.simulate_var,VAR.plotsim,VARResults.irf_errband_mc,VARResults.irf_resim,SVARResults.sirf_errband_mc, and theIRAnalysis.plot/plot_cum_effects/errband_mc/err_band_sz1/err_band_sz2/err_band_sz3/cum_errband_mcfamily):seed->rng.ARDL.bounds_test,graphics.functional.hdrboxplot(seedandkernel_seed), andsandbox.panel.random_panel.PanelSample:seed->rng.The internal
statsmodels.tools.rng_qrng.check_random_statehelper (which also acceptsscipy.stats.qmc.QMCEngineinstances) is now used consistently across these code paths to turn whatever is passed viarnginto an actualGenerator/RandomStateinstance.
See Breaking Changes and Deprecations below for what this means for existing code. PR #9737, PR #9615, PR #9831, PR #9947, PR #9950
Formula engine: patsy is no longer the only option#
statsmodels now has an abstracted formula-handling layer
(statsmodels.formula) that can use either patsy (the default engine
when it is installed, for backward compatibility) or formulaic as the engine behind the
formula interface (smf.ols("y ~ x", data=df), etc.). The engine can be
selected explicitly with the SM_FORMULA_ENGINE environment variable
("patsy" or "formulaic"). formulaic is now a required runtime
dependency (formulaic>=1.1.0) even when patsy continues to be used
as the default engine. This lays the groundwork for statsmodels to move away
from patsy, which has been in low-maintenance mode for several years.
PR #9423, PR #9470
Build system: meson-python replaces setuptools#
statsmodels’ build backend switched from setuptools (with a custom
setup.py) to meson-python.
Anyone building statsmodels from source needs Meson/Ninja available and a
build environment satisfying the new build requirements (numpy>=2.0,
scipy>=1.13, cython>=3.0.13). This does not affect users installing
prebuilt wheels from PyPI. PR #9634
New robust estimation tools#
Several new robust estimators and supporting tools were added:
statsmodels.robust.covariance.CovDetMCD(minimum covariance determinant with deterministic starts),CovDetS(S-estimator for mean/covariance with deterministic starts), andCovDetMM(an MM-estimator built on top ofCovDetS). These are preliminary/experimental APIs. PR #9227, PR #8129statsmodels.robust.resistant_linear_model.RLMDetSMM, an MM-estimator for regression using S-estimator starting values, plus additional robust norms and supporting tools. PR #9186Fixes and additions to
scale.Huberand a new robust M-scale estimator. PR #9210
New models and statistical tests#
statsmodels.multivariate.multivariate_ols.MultivariateLS, a new multivariate least-squares model. PR #8919statsmodels.tsa.stattools.leybourneimplementing the Leybourne-McCabe stationarity test. PR #9399A two-sample z-test for the unequal-variances case. PR #8959
"one-sided"alternative hypotheses forproportion_confintandconfint_poisson. PR #9249, PR #9255Games-Howell post-hoc test added alongside a fix to Tukey’s HSD for the unequal-variance case. PR #9487
A sample-size calculation for the Wilcoxon/Mann-Whitney test. PR #9401
Order validation for the Hannan-Rissanen ARMA estimator. PR #9819
ARDLmodels can now use a"ctt"trend. PR #9518x13_arima_analysisgained seasonality fit diagnostics and an optional raw spec parameter. PR #9498, PR #9550
New and improved plots#
statsmodels.graphics.tsaplots.plot_ccfandplot_accf_gridfor plotting cross-correlations and cross-correlation matrices, andccfgained an option to return confidence intervals. PR #8782, PR #8783statsmodels.graphics.tsaplots.seasonal_diagnostic_plot, a new seasonal diagnostic plot. PR #9787statsmodels.graphics.regressionplots.add_ellipsefor adding confidence ellipses to scatter plots. PR #9815qqplot_2samplesaccepts additional plot keyword arguments. PR #9544
GLM and other model enhancements#
GLMResults.get_margeff(marginal effects for GLM). PR #8889GLM models now preserve the names of input pandas Series. PR #9130
het_whitegained an option to omit interaction (cross) terms. PR #9691Faster computation of state space “news”/revision impacts, and a significant performance optimization of VECM to avoid an \(O(T^2)\) projection matrix. PR #8937, PR #9720
Platform and packaging compatibility#
Cython 3 compatibility, and compatibility of the
tsa.statespaceCython code with SciPy ILP64 builds. PR #9078, PR #9798Experimental Pyodide/WebAssembly support and CI jobs. PR #9270, PR #9343
Free-threaded (no-GIL) CPython compatibility work, including free-threading-compatible Cython modules and CI coverage. PR #9717
Notable bug fixes#
A few of the more consequential correctness fixes in this release (see Bug Fixes below for the full list):
families.Binomial.deriv()was missing a division bynand returned an incorrect value; it now correctly returns1 - 2 * mu / n. PR #9862The log-likelihood computation for
ETSModelwas corrected. PR #9400A state space model transition-timing bug was fixed. PR #9688
anova_lmsilently returnedNaNp-values when models were passed in reverse order. PR #9852Numerical instability in VIF was fixed by standardizing the design matrix before computing it. PR #9835
Breaking Changes and Deprecations#
seed/random_state -> rng (SPEC-007)#
As described above, wherever a function or model previously accepted
seed or random_state to control randomness, it now accepts rng
instead. The old keyword names still work but emit a FutureWarning
pointing at rng; they will be removed in a future release. If your code
passes seed= or random_state= by keyword to statsmodels functions,
you should switch to rng= to avoid the warning (and future breakage).
Positional usage is unaffected in most cases since rng occupies the same
position the old keyword did.
Minimum dependency versions raised#
NumPy: 1.18 -> 1.22.3
SciPy: 1.4 -> 1.8
pandas: 1.0 -> 1.4
patsy: 0.5.2 -> 0.5.6
formulaic: new required runtime dependency, >=1.1.0Building from source now requires NumPy >= 2.0, SciPy >= 1.13, and Cython >= 3.0.13 (see the meson-python migration above). This does not affect users installing wheels from PyPI.
Deprecated parameters removed entirely#
The following previously-deprecated (not previously-working) parameters and behaviors were removed as part of a general deprecation clean-up (PR #9936):
grangercausalitytests: theverboseparameter (deprecated since 0.14) has been removed. The function no longer prints results; use the returned dictionary as before.AutoReg/ar_select_order: theold_namesparameter (pre-0.12 variable naming, deprecated since 0.13) has been removed.kpss: passingnlags=Nonenow raises aValueErrorinstead of warning and silently falling back to'auto'. Pass'auto','legacy', or an explicit integer.A number of internal compatibility shims for very old NumPy/SciPy/Python versions were removed from
statsmodels.compat, includingcompat.numpy.lstsq,NP_LT_114,compat.python.asstr,asunicode,lfilter, andcompat.scipy.SP_LT_16/SP_LT_17(along with the vendoredmultivariate_tfallback they guarded). These were internal implementation details, not public API, but could have been imported directly.
Vendored pandas private APIs#
pandas has been privatizing or removing several small utilities that
statsmodels relied on (cache_readonly, deprecate_kwarg,
Appender, Substitution). statsmodels now vendors its own copies of
these (in statsmodels.compat.pandas and
statsmodels.tools.docstring_helpers) so behavior stays stable across
pandas versions, including pandas 3. PR #9615, PR #9820, PR #9831
Other removals#
New Features and Enhancements#
Enhancements
Outlier-robust covariance estimation. PR #8129
ccfcan optionally return confidence intervals. PR #8782Plot cross-correlations and the auto/cross-correlation matrix. PR #8783
Plot the prediction curve over a scatter plot in
GLMGamResults.plot_partial. PR #8881Add
get_margeffto GLM. PR #8889Add
MultivariateLS. PR #8919Faster computation of state space revision impacts. PR #8937
Two-sample z-test, unequal-variances case. PR #8959
Improve lag selection in
pacf. PR #9016Add Cython 3 compatibility. PR #9078
GLM models now save the names of input pandas Series. PR #9130
Robust: additional tools and norms. PR #9186
Add
CovDetMCD,CovDetMM,RLMDetSMM, and related estimators. PR #9227Add a
"one-sided"alternative forproportion_confint. PR #9249Add an alternative option to
confint_poisson. PR #9255Add optional parameters to
summary_colto indicate fixed effects. PR #9280Ensure returned arrays are owned (not views). PR #9334
Improve precision of a diagnostic printout (
mean_diff:.3g). PR #9388Add the Leybourne-McCabe stationarity test. PR #9399
Add a sample-size calculation for Wilcoxon/Mann-Whitney tests. PR #9401
More reliable casting of pandas data. PR #9407
Add an abstracted formula engine supporting
patsyandformulaic. PR #9423Add
rufflint support. PR #9453x13_arima_analysiscan produce seasonality fit diagnostics. PR #9498Allow the ARDL model to use a
"ctt"trend. PR #9518Add plot keyword arguments to
qqplot_2samples. PR #9544x13_arima_analysisgained an optional raw spec parameter. PR #9550Support array-like and pandas-like data more broadly. PR #9582
Add a “no cross terms” option to White’s heteroscedasticity test. PR #9691
Add missing attributes to
AutoReg. PR #9750Add a seasonal diagnostic plot to
graphics.tsaplots. PR #9787Make
tsa.statespaceCython usage compatible with SciPy ILP64 builds. PR #9798Allow seasonal-differencing-only models with non-seasonal estimators. PR #9811
Add
add_ellipseto graphics, and support passingx/yarrays. PR #9815Add order validation to the Hannan-Rissanen estimator. PR #9819
Vendor
AppenderandSubstitutiondocstring helpers from pandas. PR #9820Vendor
cache_readonlyanddeprecate_kwargfrom pandas’ private API. PR #9831Report the last root-finder value in the
solve_powerconvergence warning. PR #9885Consistently use
rngto move towards SPEC-007. PR #9950
Performance
Optimize VECM memory/speed by avoiding an \(O(T^2)\) projection matrix. PR #9720
Notable Bug Fixes#
Fix a typo in the
InfeasibleTestErrorexception string. PR #8878Correct diagnostics for changes in pandas. PR #8887
MNLogit Wald tests: fix
ravel, stringcov_names. PR #8907Fix writing a read-only array under pandas 2 copy-on-write. PR #8942
Fix an issue in
seasonal.py. PR #9029Ensure ARIMA simulation is reproducible. PR #9165
Fix
scale.Huberand add a robust M-scale. PR #9210Correct
cov_kwargs->cov_kwds. PR #9240Ensure the Zivot-Andrews test does not overwrite its input. PR #9311
Avoid an in-place modification bug. PR #9385
Correct
residfromUECM. PR #9390Correct the x/y label location in
qqplot_2sample. PR #9394Remove an incorrect
methodassignment in GLM’ssummary2. PR #9396Ensure the Hessian is skipped where appropriate. PR #9398
Correct the log-likelihood computation for
ETSModel. PR #9400Ensure VAR can forecast with 0 lags. PR #9413
Correct
DatetimeIndexhandling. PR #9457Correct handling of
PeriodIndexinseasonal_decompose. PR #9461SVAR: fix
A/Bdtype and a one-parameter score shape bug. PR #9468Fix formula
evaldepth in model selection. PR #9471Tukey’s HSD: fix an unused variance and add Games-Howell for the unequal-variance case. PR #9487
Fix a bug in
Runs.runs_testfor the case of a single run. PR #9524Make the Binomial family more robust to the corner case
mu=0,endog=0. PR #9581Fix the
add_trenderror message to correctly identify constant columns. PR #9636Fix conversion of 1-d arrays to scalars. PR #9673
Fix a state space model transition-timing bug. PR #9688
Pass
alphathrough toplot_predict. PR #9728Fix an incorrect length comparison in endpoint transformation logic. PR #9729
Fix compilation errors in
statespace/meson.build. PR #9738Fix patsy
eval_envhandling inFormulaManager. PR #9739Raise an error for invalid
endoginput inemplike.DescStat. PR #9747Add an informative error message when Hessian inversion fails in
fit_regularized. PR #9757Replace bare
exceptclauses withexcept Exception. PR #9758Treat empty docstrings as
Nonein theDocstringclass. PR #9773Fix
use_boxcoxcontrol flow inExponentialSmoothing.fit. PR #9797Override the
residproperty inUECMResults. PR #9812Avoid a division by zero in
estimate_location. PR #9814L-BFGS-B: respectdisp=Falseinstead of always printing output. PR #9823Remove a dead assignment to
cov_pin GLM’sfit. PR #9826Fix the
GLMInfluence.hat_matrix_diagmethod name. PR #9830Fix VIF numerical instability by standardizing the design matrix. PR #9835
Skip summary diagnostics when
slim=True. PR #9844Fix
anova_lmsilently returningNaNp-values when models are passed in reverse order. PR #9852Set
k_exog_useronSVARResultssosummary()works. PR #9853Fix
Binomial.deriv()to correctly return1 - 2*mu/n(it was missing the division byn). PR #9862Record the robust scale in
RLM.fit_history. PR #9866Fix the
NegativeBinomialcheck for the optionalalphaparameter. PR #9877Return
nanfromPower.solve_powerwhen it fails to converge, rather than a misleading value. PR #9884Correct several parameter names in docstrings (
prob_infl,bin_edges,pred_kwds,param_nums,mu1_low). PR #9886Fix
DiscreteResultscrashing withfull_output=0. PR #9887Fix an
ccovfshape mismatch for arrays of different lengths. PR #9888describe/Descriptionnow handle a 0-row (empty) input gracefully. PR #9899Fix an issue with random generation. PR #9901
Attach
mlefitattributes to the results instance so they appear indir(). PR #9902Do not pass
hesstoL-BFGS-B/TNCin_fit_minimize, which do not accept it. PR #9908Read the entropy integration limits from the kernel. PR #9919
Populate
_retain_colsinout_of_samplewithout requiring a priorin_samplecall. PR #9920Correct a test that relied on the removed random-state singleton. PR #9924
Fix an import failure when matplotlib is not installed. PR #9925
Unify
group_sumsorientation and fixgroup_demean. PR #9933
Build, Packaging, and Infrastructure#
Migrate the build backend from
setuptools/setup.pytomeson-python. PR #9634Update minimum dependency versions (multiple passes). PR #9110, PR #9112
Add experimental Pyodide/WebAssembly support and CI jobs, including fixing an OpenBLAS symbol error under Emscripten. PR #9270, PR #9343
Avoid non-deterministic ordering in
include_dirslists (reproducible builds). PR #9296Further clean-up of the build configuration. PR #9632
Generate free-threading (no-GIL) compatible Cython modules. PR #9717
Ensure the
libmC math library is linked for all build targets. PR #9778Remove the
oldest-supported-numpybuild workaround now that NumPy 2 is the floor for building from source. PR #9312CI: add Python 3.13/3.14 (including free-threaded 3.14t) jobs, drop active Python 3.9 testing, and pin GitHub Actions to full commit SHAs for supply chain hardening. PR #9547, PR #9656, PR #9709, PR #9913, PR #9843
Routine dependency updates for GitHub Actions were kept current via dependabot throughout the release cycle (
actions/checkout,actions/setup-python,actions/setup-node,github/codeql-action,pypa/cibuildwheel,r-lib/actions/setup-pandoc, andts-graphviz/setup-graphviz) across roughly two dozen pull requests not individually itemized here.
Documentation#
In addition to numerous individual typo, notebook, and docstring
corrections, this release cycle included a large, systematic effort to
bring docstrings across the codebase in line with the numpydoc standard
(module by module: discrete, genmod, stats, tsa/
statespace, base/compat/datasets, graphics,
imputation/multivariate/nonparametric, emplike/duration,
treatment/gam, tools, othermod/regression/robust,
and more), plus a documentation theme change to pydata-sphinx-theme and
a pass over example notebooks to fix formatting and broken links.
Correct links to notebooks. PR #8886
Correct a typo in the
WLS.loglikedocstring. PR #8900Add install instructions for the nightly build. PR #8941
Correct the signature of
CopulaDistribution. PR #8946Fix an inconsistency in
var_model.py. PR #8948Fix inclusion of plots in the docs. PR #8963
Include the correct plot in
scatter_ellipsedocs. PR #8974Various small typo fixes. PR #9011, PR #9082, PR #9192, PR #9208, PR #9285, PR #9397, PR #9462, PR #9532, PR #9558, PR #9626, PR #9848, PR #9850, PR #9873, PR #9941
Fix broken plots/content in
linear_regression_diagnostics_plots. PR #9158Fix interaction and other example notebooks. PR #9216, PR #9218, PR #9551, PR #9552, PR #9554, PR #9617, PR #9621, PR #9683, PR #9718, PR #9724, PR #9784, PR #9864
Update the
ztest/ztest_meanp-value description. PR #9226Improve documentation for regression diagnostics, stats, and summary. PR #9230
Generate docs for
plot_ccfandplot_accf_grid. PR #9299Fix documentation of
AutoReg. PR #9310Add a
CITATIONfile. PR #9346Improve documentation of
acfandplot_acf. PR #9348Clarify notation for the error term in the regression docs. PR #9361
Fix docstring formula display in the SVAR class. PR #9372
Improve docs for
ExponentialSmoothingand related places. PR #9391Update the mediation tutorial documentation. PR #9422
Remove an empty cell from an ARMA example notebook. PR #9483
Fix a broken link to a citation reference. PR #9561
Document currently supported Python versions. PR #9588
Fix the Gamma
loglike_obsdocstring and clarify weight parameterization; align Gamma/Negative-Binomial notation in the GLM families table. PR #9660, PR #9890, PR #9892, PR #9893Fix a broken academic reference in
anova.py. PR #9749Fix an import in the api-structure page. PR #9755
Add the seasonal diagnostic plot to the docs. PR #9788
Correct the
PredictionResults.conf_intdocstring. PR #9813Fix incorrect parameter names in
deconvolve,powerdiscrepancy, andVECMResults.predictdocstrings, and fix formula rendering inpowerdiscrepancy. PR #9838, PR #9839Switch the documentation theme to
pydata-sphinx-theme. PR #9861Improve math formulas in
robust.normsdocstrings. PR #9876Add missing
PoissonResults/NegativeBinomialPResultsto the discrete-models autosummary. PR #9914Systematic docstring fixes by module: discrete (PR #9929), genmod (PR #9930), stats (PR #9931), tsa/statespace (PR #9934), base/compat/ datasets (PR #9935), graphics (PR #9937), imputation/multivariate/ nonparametric (PR #9938), othermod/regression/robust (PR #9940), tools (PR #9945), statespace (PR #9946), emplike/duration (PR #9943), treatment/gam (PR #9944).
Update notebooks for the deprecations introduced in this release. PR #9939
Testing, Linting, and Maintenance#
A substantial amount of routine maintenance went into keeping the test
suite green against upstream changes in NumPy, SciPy, and pandas (including
pandas copy-on-write and preparation for pandas 3), adopting ruff for
linting in addition to flake8, running isort/pyupgrade across
the codebase, relaxing overly tight test tolerances, and improving thread
safety of the test suite ahead of free-threaded CPython support. Selected
items:
Reduce direct use of the global
np.randomstate in the library and in tests. PR #9878, PR #9879, PR #9737Prepare for pandas 3 (string dtype changes, removed features). PR #9245, PR #9247, PR #9602, PR #9689, PR #9722
Adopt
rufffor linting. PR #9453, PR #9642, PR #9643, PR #9650Run
isortacross the codebase. PR #9855Remove the obsolete, empty
statsmodels.interfacepackage. PR #9721Improve thread safety of the test suite. PR #9742, PR #9904, PR #9910
Add CI coverage for Python 3.13/3.14 and free-threaded CPython. PR #9547, PR #9656, PR #9709
Development summary and credits#
Thanks to everyone who contributed code, documentation, bug reports, and
review to this release cycle. The following list of contributors is
generated from git log between v0.15.0.dev0 and the current
development head, and may not be complete or fully deduplicated across
differently-configured git identities:
Aditi Juneja, Adrian Ross, Agriya Khetarpal, Alex Alborghetti, Andrés, Andrés López, Anh Trinh, Aniket, Aniket Singh Yadav, Anselm Hahn, Antoine Mayerowitz, Anuraag Pandhi, Artem Glebov, Ben, Benjamin Leff, Bortlesboat, Caleb Lindgren, Chad Fulton, Christine P. Chai, Clément Fauchereau, Daan Knoope, David Ivanov, Deshan, Dhairya Motta, Dhruvil Darji, Eden Rochman, Elton Chang, Erich Morisse, Eugen Goebel, Evan Lyall, Evgeni Burovski, FuturMix, Hadi Dayekh, Harish Bhavandla, IsaacP, IntegralIndefinida, Illia Polovnikov, Iman, Jesse W. Collins, Jim Varanelli, Joey Scanga, Josef Perktold, Joshua Markovic, Justin Mahlik, Kaif, Kevin Sheppard, Kevin Gregory, Kumar Aditya, Lakshmi786, Luke J, Maciej Skorski, Manlai Amar, Marc Bresson, Mathias Hauser, Maxime Gourguechon, Melissa Wu, Michał Górny, Michel de Ruiter, Naimish Machchhar, Pranav Achar, Puneet Dixit, Rahul Rathnavel K, Ralf Gommers, Rebecca N. Palmer, RoyS, Sebastian Pölsterl, Shamus, Solaris-star, Sreekant Baheti, Tartopohm, Vedant Madane, Vikram Kumar, Viktor, Vitaliy, Wali Reheman, Will Tirone, YangWu1227, Zbigniew Jędrzejewski-Szmek, Zhengbo Wang, and many others.
These lists are automatically generated based on git log and may not be
complete.