wranglefy
Automated data import and wrangling from many formats.
wranglefy is a small, pandas-powered library that takes the friction out of the first mile of data work: getting messy files of any common format into a clean DataFrame. Point it at a file and it figures out the format; hand it a frame and it tidies column names, normalises missing values, infers types, de-duplicates rows, and more — in one call or as a readable, chainable pipeline.
import wranglefy as of
df = of.read("sales.xlsx") # format auto-detected from extension/content
clean = of.auto_wrangle(df) # snake_case cols, typed, de-duped, tidy NaNs
# …or do both at once:
clean = of.load("sales.csv.gz", wrangle=True)
Why
Real datasets arrive as CSVs with "N/A" sprinkled through them, Excel exports with "First Name" columns, gzipped JSON lines, the occasional Parquet file, and worse. wranglefy collapses the repetitive boilerplate of detecting formats and cleaning frames into a couple of well-tested calls, while staying out of your way when you need full control (every reader passes **kwargs straight through to pandas).
Installation
pip install wranglefy
The core install only depends on pandas/numpy and reads CSV, TSV, JSON, JSON Lines, and Pickle. Heavier formats live behind optional extras:
pip install "wranglefy[excel]" # .xlsx / .xls / .ods
pip install "wranglefy[parquet]" # Parquet / Feather / ORC (pyarrow)
pip install "wranglefy[html]" # HTML tables
pip install "wranglefy[xml]" # XML
pip install "wranglefy[spss]" # SPSS .sav
pip install "wranglefy[all]" # everything
Supported formats
| Format | Extensions | Extra |
|---|---|---|
| CSV | .csv (+ .gz, .zip, .bz2, .xz) |
core |
| TSV | .tsv, .tab |
core |
| JSON | .json |
core |
| JSON Lines | .jsonl, .ndjson |
core |
| Pickle | .pkl, .pickle |
core |
| Excel | .xlsx, .xls, .xlsm, .ods |
excel |
| Parquet | .parquet, .pq |
parquet |
| Feather | .feather |
parquet |
| ORC | .orc |
parquet |
| HTML tables | .html, .htm |
html |
| XML | .xml |
xml |
| Stata | .dta |
core |
| SAS | .sas7bdat, .xpt |
core |
| SPSS | .sav, .zsav |
spss |
Reading data
import wranglefy as of
# Single file — format detected from extension, then content if needed.
df = of.read("data.parquet")
# Force a format (e.g. an extensionless file or a buffer).
df = of.read(file_obj, format="csv")
# Read & concatenate many files; tag each row with its source.
df = of.read_many("exports/2024-*.csv", add_source_column=True)
# Inspect what wranglefy can do.
of.supported_formats()
of.detect_format("archive/data.json.gz") # -> "json"
Wrangling data
One-shot
clean = of.auto_wrangle(df)
The default pipeline: clean column names → strip strings → standardise missing values → drop empty rows/columns → infer types → de-duplicate. Every step is a keyword you can switch off, and fill_missing / drop_constant can be switched
on:
clean = of.auto_wrangle(
df,
infer_types=True,
dedupe=False,
drop_constant=True,
fill_missing="median", # or True for the "auto" strategy
optimize_memory=True, # downcast floats/ints & categorise strings
redact_pii=True, # auto-hash emails, ssns, etc.
clip_outliers=True, # clip numeric outliers using IQR
)
Chainable pipeline
For full control, use the Wrangler directly. It copies the input (never
mutates it) and records each operation in .log:
from wranglefy import Wrangler
wr = (
Wrangler(df)
.clean_columns() # "First Name" -> "first_name"
.strip_strings()
.standardize_missing(["TBD", "???"]) # extend the default sentinel set
.drop_empty(axis="both")
.infer_types(threshold=0.95, category=True)
.fill_missing("auto")
.clip_outliers(method="iqr") # cap statistical anomalies
.redact_pii(method="mask") # *** out sensitive columns
.optimize_memory() # shrink memory footprint safely
.dedupe(subset=["id"])
)
clean = wr.to_frame()
print(wr.log) # ['clean_columns', 'strip_strings', ...]
# Drop into raw pandas whenever you need to:
wr.apply(lambda d: d[d["score"] > 0])
Operations at a glance
| Method | What it does |
|---|---|
clean_columns() |
Normalise headers to unique snake_case identifiers |
strip_strings() |
Trim whitespace from every text cell |
standardize_missing() |
Turn "", "NA", "null", "-", … into real NaN |
drop_empty() |
Remove all-NaN rows and/or columns |
drop_constant() |
Remove columns with a single unique value |
infer_types() |
Coerce text to bool / numeric / datetime / category (threshold-based) |
dedupe() |
Drop duplicate rows |
fill_missing() |
Impute via auto/mean/median/mode/zero/ffill/bfill/constant/drop |
optimize_memory() |
Downcast numeric types (e.g. float64 -> float32) and categorise strings |
redact_pii() |
Automatically identify and hash/mask sensitive PII columns |
clip_outliers() |
Cap numeric outliers using statistical bounds (IQR or Z-Score) |
apply(func) |
Escape hatch for any df -> df transform |
Development
pip install -e ".[dev]"
pytest
License
MIT © Devisri Bandaru
Metadata
Release files for wranglefy 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| wranglefy-0.1.0.tar.gz | 21.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wranglefy-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.3 kB
Release files / wranglefy-0.1.0.tar.gz
| Download URL | wranglefy-0.1.0.tar.gz |
|---|---|
| Size | 21.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5b8c70a09d0bb7e8bc3255e559e94d1f385a957d2fa405f8ca3c2d1126adeab7
|
|
BLAKE2b-256 checksum How to use checksums |
885d8cfe12bf0c3ba61e55604db3e00d9fb30c0dc1fd48fc64ac58e65989548c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Release files / wranglefy-0.1.0-py3-none-any.whl
| Download URL | wranglefy-0.1.0-py3-none-any.whl |
|---|---|
| Size | 16.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6c588455a113e79305be5e39651edc2c4957f948e6a8a65f3f5f36fd4b9be4cd
|
|
BLAKE2b-256 checksum How to use checksums |
5c5df21576176d00e8e9ac3aa493ab78b194076871e23fa4a720dd50c18caa0a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|