Python’s Time Series Toolbox: 7 Libraries and How to Choose Between Them
Ask five engineers how they build a time series pipeline in Python and you may get five different stacks. One reaches for statsmodels out of habit, another wraps everything in sktime, a third has quietly standardized on Nixtla’s tooling, and a fourth is running a deep learning model that nobody else on the team can reproduce.
This is not a sign that the ecosystem is broken. It is a sign that “time series analysis” is not one task. Statistical forecasting, machine learning pipelines, deep learning and anomaly detection each carry their own data formats, assumptions and failure modes, and the libraries that serve them have grown up separately. The question worth asking is not which library is best, but which task each one was actually built for.
Here is the landscape, library by library, and a practical way to choose between them.
The fragmentation problem
The split is not arbitrary. It follows the underlying mathematics. Classical statistical models make assumptions about the data generating process, for example about stationarity, autocorrelation and seasonality, that machine learning and deep learning approaches do not. Machine learning approaches typically frame forecasting as a supervised regression problem, using lag features and a feature matrix. Deep learning architectures want long sequences and a lot of compute. Anomaly detection often wants none of the above, because the question is not “what happens next” but “what is unusual here.”
Each of those worldviews produces a different API, a different expected input shape and a different set of diagnostics. An engineer assembling a workflow usually ends up gluing two or three libraries together, and the glue is where bugs live. The libraries below are best understood as answers to specific questions rather than competitors in a single race.
statsmodels: classical models, built for interpretation
statsmodels is the first choice when interpretability matters as much as predictive power. It implements the classical statistical models that economics, finance and operations research have relied on for decades, and it reports coefficients, standard errors and confidence intervals rather than just a point forecast.
That matters more than it sounds. A gradient-boosted model might beat ARIMA on error metrics and still be useless in a setting where someone has to explain the forecast to a regulator, a budget committee or a trading desk. If your deliverable includes a sentence beginning “the model expects,” statsmodels gives you the vocabulary to finish it.
One caution: a fitted statsmodels model is not a forecast. It is a bundle of estimates, covariance structure and decomposition state, and it is easy to extract one attribute and walk away with less than the model actually knows. Our research digest on Statsmodels Time Series Tricks: Stop Leaving Uncertainty on the Table digs into what a fitted model actually contains and how much of it most forecasting code leaves unused.
pmdarima: automating the tedious part of ARIMA
Fitting ARIMA means choosing three orders: p, d and q. Doing that by hand, across dozens or hundreds of series, is one of the most tedious jobs in classical forecasting. pmdarima brings R’s auto.arima behavior to Python, wrapping statsmodels to search the order space automatically.
That makes it useful in two situations: generating a fast statistical baseline before you invest in anything heavier, and running automated forecasts across many series where per-series manual tuning is not realistic.
The caveat is maintenance. The project’s GitHub repository shows a slowing release cadence in recent years, so check the changelog and open issues before pinning it into a new production pipeline. A stable library with a quiet repository is often fine, but you want to know that going in rather than discovering it during a dependency upgrade.
sktime: one interface, many model families
sktime exists specifically to address the fragmentation problem. It provides a unified interface spanning forecasting, classification, regression, clustering and annotation, and it covers classical statistics, machine learning and deep learning under that single API.
The payoff is comparison. When every model family speaks the same interface, you can swap estimators, run the same cross-validation scheme and compare results without rewriting your evaluation harness. If your workflow needs to be systematic, reproducible and easy to audit across model families, sktime is built for exactly that. It is less a modeling library than a coordination layer, and that is the point.
Darts: a broader toolkit in one package
Darts takes a different route to a similar destination. Where sktime unifies access to other libraries’ algorithms, Darts implements classical, machine learning and deep learning models directly. The catalog in a single package includes exponential smoothing, ARIMA, gradient-boosted regression and several deep learning architectures.
Its emphasis falls on probabilistic forecasting and multi-series scale, which makes it a reasonable fit when you need prediction intervals across a large collection of related series and would rather not maintain three separate dependencies to get them. The trade-off is the usual one for integrated toolkits: you get coherence and convenience, at the cost of some of the flexibility that comes from composing specialized libraries yourself.
stumpy: finding patterns, not predicting them
stumpy computes the matrix profile, a structure that records the distance between every subsequence in a series and its nearest neighbor. From that single computation you get motif discovery, discord detection and pattern discovery, all without labeled data.
The output is descriptive rather than predictive, and that is where its production value lies. A forecasting model tells you what to expect, and a matrix profile tells you when the shape of the incoming signal has stopped looking like anything it has seen before. If you are building monitoring on top of prediction, stumpy is the layer that does not need a training set.
PyOD: anomaly detection at scale
PyOD is the most comprehensive library for anomaly detection on tabular and multivariate feature matrices. It implements more than 60 detection algorithms under one interface, and it has expanded beyond tabular data to time series, graph, text and image data.
In practice, though, it is still most often applied to engineered feature matrices: rolling statistics, lag features, frequency components. That reflects how anomaly detection usually works on time series rather than any shortcoming in the library. You compute features that compress the temporal structure, then hand the matrix to a detector. PyOD’s value is having more than 60 detectors behind one API so you can find out which one suits your data instead of assuming.
NeuralForecast: when simpler models plateau
NeuralForecast, from Nixtla, brings a large collection of neural forecasting architectures to Python in a production-friendly package. It is positioned for the moment when classical and machine learning models have stopped improving and the remaining error looks structural rather than tunable.
It sits inside a coherent ecosystem: StatsForecast for fast classical models, MLForecast for gradient boosting, and NeuralForecast for the neural tier. That layering is itself a design argument. Start simple, measure, and only escalate when the evidence says the simpler model has hit its ceiling. The escalation path is smoother when all three tiers share conventions.
How to choose
| Question you are asking | Library | Caveat |
|---|---|---|
| How do I explain this forecast? | statsmodels | A fitted model is not a forecast; extract uncertainty deliberately |
| What is a fast ARIMA baseline? | pmdarima | Check release cadence before production use |
| How do I compare model families fairly? | sktime | A coordination layer, not a self-contained model catalog |
| How do I get prediction intervals across many series? | Darts | Integrated toolkit, less flexible than composing specialized libraries |
| What patterns exist, with no labels? | stumpy | Descriptive, not predictive |
| Which detector fits my feature matrix? | PyOD | Usually applied to engineered features, not raw sequences |
| What if simpler models have plateaued? | NeuralForecast | Escalate only after measuring the simpler tiers |
Then check maintenance. A library’s release cadence is part of its fitness for production, and a slowed repository is a real signal even when the code still works.
The final piece of advice from the source is the one that matters most: apply every candidate library to the same dataset and compare the results yourself. Benchmark tables are averages over datasets that are not yours, and a library that wins on a public leaderboard can lose badly on your particular series. Running the comparison is also how you learn why the models behave as they do, which teaches you more about your data than any table can.
Fragmentation is the price of a field with genuinely different problems. The engineers who navigate it well are not the ones who picked the “best” library. They are the ones who can say, precisely, what question they are asking.