# pyjanitor: readable data cleaning APIs for pandas DataFrames

> pyjanitor extends pandas DataFrames with verb-based cleaning methods that fit into method chains. It is useful for analysts and Python developers who want readable preprocessing code, although its dependency requirements and experimental modules deserve scrutiny.

**pyjanitor-devs/pyjanitor** — Clean APIs for data cleaning. Python implementation of R package Janitor

- Repository: https://github.com/pyjanitor-devs/pyjanitor
- Website: https://pyjanitor-devs.github.io/pyjanitor
- Stars: 1,498 · Forks: 205
- Language: Python
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/pyjanitor-devs-pyjanitor

## Why pyjanitor targets pandas preprocessing chains

pyjanitor solves a readability problem in pandas data cleaning. A typical preprocessing job is ordered: create a DataFrame, remove a column, discard incomplete rows, rename fields, and derive another column. Those operations often depend on one another, but ordinary pandas code can split the sequence across assignments and mutation statements.

The project began as a Python implementation of the R `janitor` package, according to the README. Its current direction adds a method-chaining API with explicit verb names such as `remove_columns`, `rename_column`, and `add_column`. This makes a chain read closer to the order in which the data is transformed. It does not replace pandas or create a separate dataframe engine. The documentation describes it as extending `pandas` with cleaning routines and supporting method chaining or pandas piping.

This makes the project most relevant to data analysts, data engineers, researchers, and developers who write repeated pandas preprocessing code. It is less compelling for a single `.dropna()` call or a one-off rename. In that case, the extra dependency and custom API do not replace much code. The value appears when a pipeline contains several transformations and its sequence matters.

The README frames those ordered transformations as a data-processing DAG. pyjanitor does not schedule that DAG or automatically resolve dependencies. It gives Python code a more explicit syntax for expressing a sequence. That distinction matters: the library improves how a chain is written, not whether its transformation logic is correct.

## How pyjanitor extends the DataFrame API

Importing `janitor` registers its DataFrame methods with pandas. The README's example then calls pyjanitor methods directly on a DataFrame created by `pd.DataFrame.from_dict(company_sales)`. The chain drops `Company1`, removes rows where `Company2` or `Company3` is null, renames the remaining company columns, and adds a `Google` column.

The key mechanism is not a new data container. It is a collection of functions usable through the extended DataFrame API. The project also describes a functional API for users who prefer passing a DataFrame as an argument. Its naming follows the R package where practical, while retaining Python-oriented use with method chaining or piping.

The documented function set covers several preprocessing categories. It includes cleaning column names, including multi-index cases, and identifying duplicate entries. It can remove empty rows and columns, add or rename columns, and encode columns as categorical values. Other routines split data into features and targets, coalesce columns, convert dates from MATLAB, Excel, or Unix formats, expand delimited categorical values into dummy variables, and concatenate or deconcatenate strings by delimiter.

That breadth creates a useful syntax layer, but it should not be mistaken for validation. The README does not claim that every transformation checks business rules, schema stability, or data quality. Users still need to decide which rows are invalid, how missing values should be handled, and whether a derived column preserves the intended meaning.

## Installing pyjanitor and running the first DataFrame chain

The README states that pyjanitor requires Python 3.11 or later. It supports PyPI, conda-forge, and pipenv. For a standard Python environment, the documented pip command is:

```bash
pip install pyjanitor
```

After installation, create a small DataFrame and import `janitor`. Importing the package is required because pyjanitor extends pandas methods.

```python
import pandas as pd
import janitor

```

The next chain demonstrates the verb-based API from the README. It removes one column, drops rows missing either selected column, renames two columns, and adds a third column.

```python
df = (
    pd.DataFrame.from_dict(company_sales)
    .remove_columns(["Company1"])
    .dropna(subset=["Company2", "Company3"])
    .rename_column("Company2", "Amazon")
    .rename_column("Company3", "Facebook")
    .add_column("Google", [450.0, 550.0, 800.0])
)
```

The README shows the resulting columns as `SalesMonth`, `Amazon`, `Facebook`, and `Google`. The original index labels are retained where rows were dropped, so `March` disappears while later rows retain their original indices.

Conda users can install the package from the channel documented in the README:

```bash
conda install pyjanitor -c conda-forge
```

The README also documents a pipenv route with prerelease dependencies:

```bash
pipenv install --pre pyjanitor
```

Use that last command only if prerelease dependencies fit the project. The ordinary `pip install pyjanitor` command is the clearest documented starting point.

## pyjanitor's dependency boundary under pandas 3.0

The current `pyproject.toml` identifies version `0.32.39`, requires Python `>=3.11`, and requires `pandas>=3.0.0`. It also pins `natsort>=8.4.0,<9`, `pandas-flavor>=0.8.1,<9`, `multipledispatch`, `scipy`, and `janitor-rs==0.6.4`. That is a larger dependency surface than a small collection of pure pandas helpers would suggest.

This is the most concrete adoption constraint. An existing pandas 2.x environment cannot satisfy the current project metadata without changing its pandas version. Changing pandas can affect unrelated code because pandas is a central dependency rather than an isolated utility. The README's Python requirement also conflicts with some classifier entries in `pyproject.toml`, which still list Python 3.8, 3.9, and 3.10. The installable metadata is the stronger source for the current minimum, while the stale classifiers are a packaging detail to verify before publishing or supporting environments.

The optional dependencies are narrower. Biology uses `biopython`, chemistry adds `tqdm`, engineering uses `unyt`, and Spark support uses `pyspark`. Documentation dependencies also include `polars`, but the project describes finance, biology, chemistry, engineering, and PySpark as experimental submodules. Those modules should not be treated as equivalent in stability to core cleaning functions without checking their documentation and tests.

The repository includes `tests/`, `docs/`, `examples/`, `CHANGELOG.md`, and contribution configuration, which is consistent with a substantial Python library. Still, the repository does not make migration notes for every pandas upgrade part of the README. Production users should inspect the changelog for the exact release they plan to install.

## Method chaining versus ordinary pandas assignment

pyjanitor is an alternative interface to pandas primitives, not an alternative to pandas itself. The README compares an imperative sequence that deletes and renames columns with a fluent pandas example that uses `.drop()`, `.dropna()`, `.rename()`, and `.assign()`. That comparison is important because modern pandas already supports readable chaining for many tasks.

Where pyjanitor differs is its vocabulary and intended breadth. `.remove_columns()` states the operation as a cleaning verb. `.rename_column()` and `.add_column()` expose project-specific operations within the same chain. Ordinary pandas remains more familiar, and its native methods can apply to more cases without relying on pyjanitor's registered extensions.

A second difference is consistency with the R package. The API documentation says pyjanitor copies R package function names where possible. That helps users familiar with `janitor` translate some routines, but Python users cannot assume every R behavior or column-selection convention is identical. The README does not provide a complete compatibility matrix.

For a compact pipeline, the custom syntax may improve readability. For a library of broad production transformations, it can also hide pandas behavior behind another abstraction. Code reviewers must understand both the pyjanitor function and the pandas operation it ultimately performs. The example's use of explicit verbs is a presentation improvement, not evidence that the data transformation is more correct.

## Maintenance signals, MIT terms, and upgrade work

The repository is not archived. Its last push was on 2026-10-16, and releases `v0.32.37`, `v0.32.38`, and `v0.32.39` were published between 2026-10-13 and 2026-10-15. Those facts indicate recent release activity, but they do not establish compatibility for every pandas version or production workload.

The project is licensed under MIT. That permits use, modification, distribution, and sublicensing under the license conditions, including preservation of the copyright and license notice. It also includes an implied warranty disclaimer and limits the licensor's liability. This is a factual reading of the license identifier, not legal advice.

Upgrade cost depends on whether pandas can move to version 3.0 or later. The current metadata may require dependency resolution, environment changes, and regression checks outside pyjanitor itself. Reviewers should use the release notes and `CHANGELOG.md` rather than assuming that frequent releases mean an existing chain will behave identically.

The Makefile defines `test`, `lint`, `docs`, `check`, and formatting targets, although it warns that it has not been fully tested and contains a release target that invokes `setup.py`. The project metadata instead uses setuptools configuration in `pyproject.toml`. This mismatch makes the Makefile a less reliable guide than the package metadata for installation and release procedures.

## Conclusion

Adopt pyjanitor when repeated pandas preprocessing is easier to understand as named, chained operations. Do not adopt it solely for basic filtering or column deletion, or if Python 3.11 and pandas 3.0 or later are unacceptable constraints. Check `pyproject.toml`, the selected cleaning functions, and any optional dependencies needed by finance, biology, chemistry, engineering, or PySpark workflows before upgrading production code.

## FAQ

### How do I install pyjanitor?

The README documents `pip install pyjanitor` and `conda install pyjanitor -c conda-forge`. It states that Python 3.11 or later is required.

### What does pyjanitor add to pandas?

pyjanitor adds verb-based DataFrame methods for cleaning and preprocessing, including removing or renaming columns, identifying duplicates, coalescing values, date conversion, and encoding columns. It also provides functional or chained usage according to the project documentation.

### Is pyjanitor suitable for production pandas projects?

The project is not archived, and its documented release activity is recent. Before adopting version `0.32.39`, verify that the environment can use Python `>=3.11` and `pandas>=3.0.0`, then review the release's changelog and relevant tests.

## Sources

- [License: MIT](https://github.com/pyjanitor-devs/pyjanitor/blob/dev/LICENSE)
- [Project website](https://pyjanitor-devs.github.io/pyjanitor)
- [pyjanitor-devs/pyjanitor on GitHub](https://github.com/pyjanitor-devs/pyjanitor)
- [README](https://github.com/pyjanitor-devs/pyjanitor/blob/dev/README.md)
- [Releases](https://github.com/pyjanitor-devs/pyjanitor/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pyjanitor-devs-pyjanitor
