Skip to main content

Pandas-like toolkit for nested JSON/NDJSON: flatten, select, explode, reconstruct

Project description

nestedframe

Pandas-style toolkit for nested JSON/NDJSON. It makes semi-structured data—event logs, API responses, tracking payloads, JSONL—feel like working with Pandas: one-line load, path selection, controlled flattening, array explode, and reconstruction back to nested records.

  • PyPI: coming soon
  • License: MIT
  • Python: 3.9+

Why

  • json_normalize becomes unwieldy on complex arrays and loses hierarchy.
  • Analysts need to switch between “preserving the original nested structure” and “an analyzable flat table”.
  • Selecting deep paths and exploding arrays while preserving parent-child relationships is repetitive and error-prone.

What

  • NestedFrame provides from_records, path-based select, controlled explode, and to_nested to reconstruct records.
  • Columns use dotted paths (e.g., user.id, meta.country). When exploding items, child fields become items.id, items.qty.

Installation

pip install nestedframe

For local development:

pip install -e .

Quickstart

from nestedframe import NestedFrame

records = [
    {"user": {"id": 1, "name": "A"}, "items": [{"id": "i1", "qty": 2}, {"id": "i2", "qty": 1}], "meta": {"country": "CN"}},
    {"user": {"id": 2, "name": "B"}, "items": [{"id": "i3", "qty": 5}], "meta": {"country": "US"}}
]

nf = NestedFrame.from_records(records)
nf.to_pandas()

nf2 = nf.explode("items")
nf2.to_pandas()

nf2.to_nested(group_by="_root_id")

Key Features

  • Dotted path columns with robust flattening of nested dicts.
  • Controlled array explode that preserves a _root_id for reconstruction.
  • Flexible column selection using fnmatch-style patterns.
  • Round-trip conversion back to nested records for export.
  • NDJSON/JSON IO helpers with .gz JSONL support.

New in this release

  • from_pandas(df) to wrap an existing DataFrame as NestedFrame while ensuring _root_id.
  • select(patterns=None, exclude=None) supports include and exclude patterns.
  • subset(include, exclude) returns a new NestedFrame with selected columns.
  • explode_many(paths) sequentially explodes multiple array paths.
  • schema() returns available columns and top-level prefixes.
  • to_ndjson(path, group_by="_root_id") writes reconstructed records to NDJSON.
  • read_jsonl(path) alias for read_ndjson, automatically supports .gz files.

IO

from nestedframe import read_json, read_ndjson, read_jsonl

nf = read_json("data.json")
nf = read_ndjson("events.jsonl")
nf = read_jsonl("events.jsonl.gz")

nf.to_ndjson("out.jsonl")

Column Selection

df = nf.select(patterns=["user.*", "meta.country"], exclude=["*.name"])
nf_sub = nf.subset(patterns=["items.*", "user.id"], exclude=["items.qty"])

Multiple Explodes

nf3 = nf.explode_many(["items"])  # add more paths as needed

API Reference

  • NestedFrame.from_records(records)
  • NestedFrame.from_pandas(df)
  • NestedFrame.to_pandas()
  • NestedFrame.select(patterns=None, exclude=None) → DataFrame
  • NestedFrame.subset(patterns=None, exclude=None) → NestedFrame
  • NestedFrame.explode(path) → NestedFrame
  • NestedFrame.explode_many(paths) → NestedFrame
  • NestedFrame.to_nested(group_by=None) → list[dict]
  • NestedFrame.schema() → dict
  • NestedFrame.to_ndjson(path, group_by="_root_id")
  • read_json(path) → NestedFrame
  • read_ndjson(path) / read_jsonl(path) → NestedFrame
  • write_ndjson(records, path)

Performance Notes

  • Explode operations iterate per-row and per-element; prefer targeted paths and pre-filtering.
  • Reconstruction uses grouping by _root_id; ensure this column persists through transformations.

Contributing

  • Run tests with pytest.
  • Please keep public APIs stable and add tests for new features.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nestedframe-0.1.1.tar.gz (8.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nestedframe-0.1.1-py3-none-any.whl (7.2 kB view details)

Uploaded Python 3

File details

Details for the file nestedframe-0.1.1.tar.gz.

File metadata

  • Download URL: nestedframe-0.1.1.tar.gz
  • Upload date:
  • Size: 8.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for nestedframe-0.1.1.tar.gz
Algorithm Hash digest
SHA256 42eca9d8244c74cc052aac7cc4757f65ef5b975c338c69c9a10adc14731edb5b
MD5 0e36f7d221dcfa8c57222c550af9224d
BLAKE2b-256 80a094b6de7ece41965716eab742d24392100d6acbf2bdb9ba459b0168e1d024

See more details on using hashes here.

File details

Details for the file nestedframe-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: nestedframe-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 7.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for nestedframe-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a512666cbe2abaf8b70450f35b8e94ef27e9aaa0f75168abf52d57852e84a3d5
MD5 a1f18b9bb746533df81e7de4b28304dd
BLAKE2b-256 14c13447352f5c6760326d6b1ac848b89f96710a3174447274a21e39bc4ba104

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page