Skip to main content

normalize-tabular-data

A terminal UI (Textual) for interactively normalizing tabular data, backed by polars for speed and gnosis-date-parser for fuzzy date parsing at Rust speed.

Load a file, see a preview, build up a pipeline of normalization operations (normalize messy dates, trim whitespace, rename a column, deduplicate, combine/split columns, drop columns), then save the cleaned result.

TUI preview

Running

Persistent install

uv tool install normalize-tabular-data
# upgrade later with:
uv tool upgrade normalize-tabular-data

Ephemeral run (no install)

uvx fetches into a throwaway environment each time:

uvx normalize-tabular-data
# pin a specific version:
uvx normalize-tabular-data==0.1.1

From a git checkout

Within the directory of the cloned repository:

uv run normalize-tabular-data

Command line

An optional FILE argument names a table to open at startup, as if you had picked it from the in-app dialog.

normalize-tabular-data data/members.csv      # or with uvx/uv run
uvx normalize-tabular-data data/members.tsv

If the file is missing or its format cannot be read, the TUI still starts — it shows an alert toast and you can open something else.

Open with a script

With --script/-s, an .ntd script is played on FILE as soon as it loads (same flow as the p key, same stop-and-rollback on a step that does not fit the file):

uvx normalize-tabular-data data/members.csv -s data/members.ntd

Headless run (-x, --run)

--run/-x skips the TUI: it opens FILE, plays SCRIPT step by step, saves the result and exits. Each operation prints to stdout as it is applied; anything else — including a failing step, named and rolled back exactly as the interactive player would — goes to stderr with a nonzero exit code.

# saves data/members-normalized.csv next to the original
uvx normalize-tabular-data members.csv -s members.ntd -x

# choose the destination (format taken from its extension):
uvx normalize-tabular-data members.csv -s members.ntd -x -o out/members.parquet

# write the CSV to a pipe instead:
uvx normalize-tabular-data members.csv -s members.ntd -x -o - | gzip > clean.csv.gz

With -o - (attached -o- works too), the transformed table is written to stdout itself and the step lines are suppressed, so stdout carries only the data. After a successful run the confirmation line goes to stderr.

Usage

Launch with normalize-tabular-data. Keys:

Key Action
f (F)ile — open a file
o (O)peration — choose an op
p (P)lay script — apply .ntd
u (U)ndo last applied step
r (R)edo
s (S)ave the data in a format
q (Q)uit

Operations

  • Normalize date(t)imes — parse a messy date column of any input format into canonical UTC datetimes at millisecond resolution; unparseable values become null. CSV/TSV/JSONLines export serializes datetime columns as second-resolution year-month-dayThh:mm:ss strings; Parquet and Excel keep the real datetime values.
  • Normalize (d)ates — the same match-anything parsing, condensed to the UTC calendar date: the column becomes date-only ISO-8601 (year-month-day); unparseable values become null.
  • Trim whitespace — strip edges and collapse internal whitespace runs, per selected columns.
  • Rename a column — click its header in the preview and type the new name.
  • Combine columns — concatenate two or more columns with a separator.
  • Split column — break one column into {col}_1..{col}_k; a blank delimiter splits on runs of whitespace.
  • Remove columns — drop selected columns entirely.
  • Deduplicate rows — on all or selected columns, keeping first or last.

Formats

Reads: CSV, TSV, JSON lines, Parquet, Excel (.xlsx/.xls — first sheet). Writes: CSV, TSV, JSON lines, Parquet, Excel (.xlsx).

Large files are previewed with a random sample of 250 rows; every operation still runs on the full data.

Operation scripts (.ntd)

Every open file keeps an internal log of the operations performed on it. When saving, the dialog offers a Save sequence of operations? checkbox (unticked by default); with it ticked, a second dialog asks where to write the script — suggested <table>.ntd; scripts always use the .ntd extension, so the name you type is saved with that suffix whatever it ends in.

The script is plain ASCII text, one operation per line, e.g.:

# normalize-tabular-data script
# source: worksite.csv
# table: /data/worksite-normalized.csv
# saved: 2026-10-05T12:30:11
date_normalize(column="Signed Up")
trim_collapse(columns=["Full Name", "Worksite", "Job Class"])
split_column(column="Full Name", delimiter="")
rename_single(column="Full Name_1", new_name="First Name")
rename_single(column="Full Name_2", new_name="Last Name")

Playing a script back

Press p (available while a file is loaded) to pick a script file: the dialog previews the highlighted .ntd file (syntax-highlighted, first 40 lines) before you confirm. Its operations are applied, in order, to the table you have open. If any step cannot be performed against the currently loaded file — a column it renames, trims or splits is missing, the operation is unknown — playing stops with an alert naming the failing step, and every step the script had already applied is rolled back, so the table is left exactly as it was.

Publishing

PyPI credentials live in $HOME/.pypirc (sections [pypi] and [testpypi]); uploads go through twine, which honors that file — uv publish does not read .pypirc, so it is not used here.

make dist       # build sdist+wheel into dist/ and run `twine check`
make testpypi   # upload to the TestPyPI sandbox (login section [testpypi])
make pypi       # upload to PyPI (login section [pypi])
twine upload    # equivalent of `make pypi`, minus a fresh build

The targets fail fast if the package metadata does not pass twine check, and twine runs with --non-interactive so a missing or wrong credential aborts the upload instead of prompting mid-run.

License

BSD 2-Clause. Copyright (c) 2026, Service Employees International Union (SEIU).

See LICENSE.

Metadata

Release files for normalize-tabular-data 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for normalize-tabular-data 0.1.3
File Size Uploaded
normalize_tabular_data-0.1.3.tar.gz 26.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for normalize-tabular-data 0.1.3
File Interpreter ABI Platform
normalize_tabular_data-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 57.5 kB

Release files / normalize_tabular_data-0.1.3.tar.gz

Download URL normalize_tabular_data-0.1.3.tar.gz
Size 26.5 kB
Tags Source
SHA-256 checksum
How to use checksums
3e7598f2d0dc412306e433047d83c9f639ea9e2b73c0632ce1e86c20598d93aa
BLAKE2b-256 checksum
How to use checksums
bbb2c9a58fcc7318a6f9b494c2065d8c96f31f489f531877e85ad6c31041e541
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.0

Release files / normalize_tabular_data-0.1.3-py3-none-any.whl

Download URL normalize_tabular_data-0.1.3-py3-none-any.whl
Size 31.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
10f16d9e80898abff93039697523df631771958f18ed38a95fbd39b85a335871
BLAKE2b-256 checksum
How to use checksums
de488d76e63d7700ebf17559f1f1dacc5c41019c370e6ecd6679530f539d67f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.0

Release history Release notifications | RSS feed

0.2.0

2 release files

0.1.5

2 release files

0.1.4

2 release files

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page