skrub: dataframe preprocessing that ends in a scikit-learn estimator
Machine learning with dataframes
At a glance
- What is it?
- skrub is a BSD-3-Clause Python library for machine learning on dataframes. Its value is in the join between pandas or Polars tables and scikit-learn pipelines; its cost is that it is still a 0.x project whose documentation ships inside the wheel.
- Who is it for?
- Adopt skrub if your team already runs scikit-learn and keeps losing time rewriting the same pandas cleaning code before every fit. Do not adopt it if you need a stable 1.0 API with long deprecation windows, or if your preprocessing is already a handful of numpy operations.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap skrub fills between a dataframe and an estimator
A pandas or Polars dataframe is not a feature matrix. Columns arrive as strings, categories, dates, free text, or nested structures, and scikit-learn estimators expect numeric arrays with consistent dtypes. The usual workaround is a pile of ad hoc pandas code that runs before fit and then has to run again, identically, at predict time. That duplication is where production bugs live: the notebook cleaned one way, the service cleaned another. skrub is a Python library aimed at that specific seam. It targets people who already use scikit-learn and dataframes together, and who want the table-to-matrix step expressed as reusable objects rather than as a script. The README states the scope plainly: skrub is a Python library that facilitates machine learning with dataframes. It does not replace scikit-learn, pandas, or Polars. It sits between them. The topics listed for the repository (data-cleaning, data-preparation, data-preprocessing, data-wrangling, dirty-data) confirm the intent: this is about the unglamorous part of the pipeline, not about model selection or training loops.
What the repository layout tells you about the architecture
The documentation and examples are bundled with the package itself, in skrub/_docs. That is an unusual choice and it is the most informative structural detail available. It means the docs version you read is the docs version matching your installed code, which removes the common failure where the website describes a newer API than the wheel you pinned. The README gives the access path directly: import skrub, then print skrub.__docs_dir__. The library also publishes a website at skrub-data.org with an examples gallery and separate learning materials, so there are two doc surfaces, but the in-package copy is the authoritative one for a given install. Beyond that, the supplied material does not describe the internal class hierarchy, the transformer base classes, or how column type inference is implemented. I cannot confirm those from what is here, and I am not going to guess at them. What is confirmable is the packaging decision: docs as a shipped artifact, which implies the maintainers expect users to consult documentation offline or in environments without web access.
Installing skrub and finding its documentation
The README states that skrub can be installed via pip or conda, and points to an installation page at skrub-data.org/stable/install.html for further detail. The pip path is pip install skrub. After installation, the README gives this exact snippet to locate the bundled documentation: import skrub, then print(skrub.__docs_dir__). That path is worth checking on the first day of an evaluation, because it tells you which documentation set you actually have. The README also documents a citation path: if you use skrub in a scientific publication, it asks you to cite the Zenodo record at doi.org/10.5281/zenodo.22231586. For a research group, that is a concrete reason to prefer skrub over unversioned internal helper code, since the artifact has a citable DOI. The project's contribution and bug-reporting routes are the standard ones: issues and discussions on the GitHub repository, with a CONTRIBUTING page on the website for direct code contributions. There is also a Discord server linked from the README, which is where the maintainers say they want to hear about use cases and challenges.
Where skrub is the wrong tool, and where the documentation is thin
The version number is the first constraint. The most recent release listed is 0.10.1, dated 2026-09-01, preceded by 0.10.0 in July 2026 and 0.9.0 in May 2026. Three releases in roughly four months is a fast cadence for a library that sits in the middle of a training pipeline. A 0.x series carries no compatibility promise, and the gap between 0.9.0 and 0.10.0 is a minor-version bump, which is exactly where a pre-1.0 project is most likely to change or remove API. Anyone pinning skrub in a production environment should read the release notes for those two versions before upgrading, and should expect to do so again at the next minor bump. The second constraint is scope. If your preprocessing is a few numpy operations on already-clean numeric columns, skrub adds a dependency and an abstraction layer for no benefit. It earns its place when the input is genuinely messy: mixed types, high-cardinality categoricals, text columns, columns that need to be derived from others. The third issue is documentation depth. The README is short and mostly points outward to the website, the examples gallery, and the bundled docs. That is not a criticism of the library, but it does mean an evaluator cannot judge the API surface from the repository alone. You have to install it and read skrub.__docs_dir__.
The real alternative: hand-written pandas inside a scikit-learn Pipeline
The honest comparison is not another dataframe-ML library. It is the code most teams already have: a ColumnTransformer with FunctionTransformer wrapping pandas operations, or a custom transformer class that implements fit and transform. That approach has one advantage skrub cannot match, which is zero learning curve for anyone who already knows pandas and scikit-learn. It has two disadvantages. First, every custom transformer is code you own and test, and the test surface grows with each new column type. Second, and more damaging, the cleaning logic tends to drift between the training path and the inference path, because the training path lives in a notebook and the inference path lives in a service. skrub's premise is that the table-to-matrix step should be a library concern with a stable interface, so both paths call the same object. That is a real difference in approach, not a cosmetic one. The trade is that you inherit skrub's release cadence and its abstractions, and you give up the ability to fix a preprocessing bug with a two-line pandas patch. Teams that iterate fast on messy data may find the direct pandas route faster to change; teams that need the same transformation in three places will feel the opposite.
Maintenance cost and the BSD-3-Clause licence
skrub is released under BSD-3-Clause, a permissive licence. In practical terms for an engineering team, that means you can use it in commercial and closed-source products, modify it, and redistribute it, provided the copyright notice and licence text are retained and you do not use the project's name to endorse your derivative without permission. I am not a lawyer and this is not legal advice; if your organisation has a licence-review process, run skrub through it rather than relying on this paragraph. The maintenance cost has two components. The upgrade cost is the 0.x cadence described above: budget time for reading release notes at each minor version. The operational cost is the dependency itself, which pulls in the dataframe and scikit-learn stack you are already using. There is no separate service, no runtime, and no data leaving your process, which keeps the footprint small. The bundled documentation in skrub/_docs is a genuine maintenance asset here: when you upgrade, the docs upgrade with the code, so the version skew problem that plagues libraries with a separate docs site does not apply.
Who should adopt skrub, and what to verify before you do
Adopt skrub if you have a scikit-learn pipeline that starts with a dataframe and a preprocessing step you keep rewriting. The fit is strongest for teams where the same cleaning logic must run in training and in serving, and where the input columns are heterogeneous enough that hand-written transformers have become a maintenance burden. Do not adopt it if you are pre-1.0-averse, if your data is already a numeric matrix, or if your team has no scikit-learn investment to build on. Before committing, do three things. Install with pip install skrub and run import skrub; print(skrub.__docs_dir__) to confirm the bundled docs match the version you pinned. Read the release notes for 0.9.0, 0.10.0, and 0.10.1 to see how much API moved in four months, and use that as your estimate of future upgrade effort. Then open the examples gallery at skrub-data.org/stable/auto_examples and find the case closest to your own data; if nothing there resembles your columns, the abstraction is probably not buying you anything yet. The library is maintained, actively released, and permissively licensed. The open question is not whether it works but whether its current API has settled enough for your release cycle.
Editorial conclusion
Adopt skrub if your team already runs scikit-learn and keeps losing time rewriting the same pandas cleaning code before every fit. Do not adopt it if you need a stable 1.0 API with long deprecation windows, or if your preprocessing is already a handful of numpy operations. Before committing, run pip install skrub, then import skrub and print skrub.__docs_dir__ to confirm the bundled documentation version matches the release you pinned, and read the 0.9.0 to 0.10.0 release notes for API changes.
Community notes