polars-schema-index
A Polars plugin for flattening nested columns with stable numeric indexing.
polars-schema-index provides a systematic way to explode/unnest nested Polars DataFrames (does not yet support LazyFrames) without overwriting columns that share the same name. It achieves this by:
- Attaching a custom
schema_indexnamespace to your DataFrame. - Renaming columns that do not end in digits with a numbered suffix.
- Iteratively flattening
Structcolumns (and optionally explodinglist[struct]columns first), so every nested field becomes a separate top-level column.
Installation
pip install polars-schema-index[polars]
On older CPUs run:
pip install polars-schema-index[polars-lts-cpu]
Usage
import polars as pl
from polars_schema_index import flatten_nested_data
# Example: flatten a deeply nested JSON structure
df = pl.read_ndjson(
source=b'''{
"body": [
{
"type": "If",
"test": {
"type": "Compare",
"left": {
"type": "Name",
"id": "x",
"ctx": { "type": "Load" }
},
"ops": [{ "type": "IsNot" }],
"comparators": [{ "type": "Constant", "value": null }]
},
"body": [{ "type": "Pass" }],
"orelse": []
}
],
"type_ignores": []
}
'''.replace(b"\n", b"")
)
flattened = flatten_nested_data(df)
print(flattened)
This gives a DataFrame with all nested fields expanded into uniquely suffixed, monotonically increasing numbered columns:
┌────────────────┬────────┬────────────┬─────────┬───┬─────────┬──────────┬──────────┬─────────┐
│ type_ignores_1 ┆ type_2 ┆ orelse_5 ┆ type_6 ┆ … ┆ type_14 ┆ type_15 ┆ value_16 ┆ type_17 │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │
│ list[null] ┆ str ┆ list[null] ┆ str ┆ ┆ str ┆ str ┆ null ┆ str │
╞════════════════╪════════╪════════════╪═════════╪═══╪═════════╪══════════╪══════════╪═════════╡
│ [] ┆ If ┆ [] ┆ Compare ┆ … ┆ IsNot ┆ Constant ┆ null ┆ Load │
└────────────────┴────────┴────────────┴─────────┴───┴─────────┴──────────┴──────────┴─────────┘
What It Solves
- No more silent overwrites of common keys (like
"type") when unnesting. - Stable numeric suffixes for each column, so even if you run multiple flatten passes, names remain unique.
- Optional exploding of list-of-struct columns before flattening them.
Key Functions
-
flatten_nested_data(df, explode_lists=True, max_passes=1000)Iteratively flattens allStructcolumns in a DataFrame or LazyFrame, and explodes anylist[struct]columns (ifexplode_lists=True). Continues until noStructcolumns remain (ormax_passesis reached). -
df.schema_index.append_unnest_relabel(df, column=...)Moves one column to the end via.permute, unnest it, then relabel newly created columns with numeric suffixes.
Note
- Column Renaming: The library appends numeric suffixes to all columns that lack them, even if they are already scalar columns. That ensures flattening never creates collisions, but it does mean your top-level columns will also gain suffixes.
- LazyFrame Support: By default, the plugin is registered for
DataFrame. If you want to use this on LazyFrames, you can register a similar namespace forLazyFrameor manually attach the plugin’s logic. I may end up supporting both.
Contributing
- Issues & Discussions: Please open a GitHub issue for bugs, feature requests, or questions.
- Pull Requests: PRs are welcome! Add tests under
tests/, update the docs, and ensure you runpytestlocally.
License
This project is licensed under the MIT License.
Metadata
Release files for polars-schema-index 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| polars_schema_index-0.1.3.tar.gz | 5.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| polars_schema_index-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 11.2 kB
Release files / polars_schema_index-0.1.3.tar.gz
| Download URL | polars_schema_index-0.1.3.tar.gz |
|---|---|
| Size | 5.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f89f4ac7639ee0a731ca058fe83583f135679f51a05ec99aab82d4e79d50d159
|
|
BLAKE2b-256 checksum How to use checksums |
25b0c7c87ad4de738f0830022e39b3d26293398cfa02ded7047d68ce2ccead6f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 16, 2026.
Transparency logRelease files / polars_schema_index-0.1.3-py3-none-any.whl
| Download URL | polars_schema_index-0.1.3-py3-none-any.whl |
|---|---|
| Size | 6.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
900f3c62210e7d8580127ae3011562c1be1f131b2fd881376b65f8ceb0124a73
|
|
BLAKE2b-256 checksum How to use checksums |
6d8811f27c5a061719b5a5ec3c8d335d94f31bd3502dc8b8e1c56b3dff544c3f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 16, 2026.
Transparency log