Metadata-Version: 2.4
Name: edasnap
Version: 0.1.0
Summary: A fast, honest first look at any pandas DataFrame — one-liner EDA helpers, no bloat.
Author: sivaraam.kr
License: MIT
Project-URL: Homepage, https://github.com/sivaraam-kr/edasnap
Project-URL: Issues, https://github.com/sivaraam-kr/edasnap/issues
Keywords: eda,exploratory-data-analysis,pandas,data-science,data-quality
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Education
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas>=1.3
Requires-Dist: matplotlib>=3.4
Requires-Dist: seaborn>=0.11
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

# edasnap

**A fast, honest first look at any pandas DataFrame — in one line each.**

`edasnap` answers the questions you ask every single time you load a new
dataset: What's the shape? What's null, and how much? What are my numeric
vs. categorical columns? Are there duplicate rows, constant columns, or
columns that are secretly IDs? Do `"USA"`, `"usa "`, and `"U.S.A"` need to
be merged into one category? Will this merge silently blow up my row count?

It's built to be the opposite of a giant auto-generated HTML report:

- **One function, one job.** No monolithic `report()` that dumps 40 sections
  you didn't ask for — call only what you need.
- **Every function returns real data** (a `dict`, a `DataFrame`, a
  matplotlib `Figure`) — never just a printout you can't reuse.
- **Never mutates your DataFrame.** Everything is read-only analysis.
- **Small on purpose.** Just pandas EDA — no bundled ML training, no
  encoding pipelines, no computer vision, no LLM calls. It's a lens on your
  data, not a pipeline.
- **Doesn't crash on messy real data** — mixed types, weird strings, and
  edge cases (empty df, all-null column, single row) are handled, not
  fatal.
- **Readable source.** Every function is short enough to read in ten
  seconds if you're curious what it's actually doing — handy if you're
  still learning pandas.

## Install

```bash
pip install edasnap
```

## Quickstart

```python
import pandas as pd
import edasnap as es

df = pd.read_csv("data.csv")

es.quick_report(df)   # runs the core checks below, in a sensible order
```

## All functions

### Structure & column types

| Function | What it tells you |
|---|---|
| `es.overview(df)` | Row/column count, total + per-column memory usage, duplicate row count |
| `es.dtypes_report(df)` | Buckets every column into `numeric`, `categorical`, `datetime`, `boolean`, or `text` |
| `es.get_numeric_cols(df)` | List of numeric column names — ready to hand to a plot or model |
| `es.get_categorical_cols(df)` | List of categorical column names |
| `es.get_datetime_cols(df)` | List of datetime column names |

```python
es.overview(df)
# {'rows': 891, 'columns': 12, 'duplicate_rows': 0,
#  'total_memory_mb': 0.29, 'memory_by_column_mb': {...}}

es.dtypes_report(df)
# {'numeric': ['Age', 'Fare'], 'categorical': ['Sex', 'Embarked'], ...}
```

### Data quality

| Function | What it tells you |
|---|---|
| `es.nulls(df)` | % missing per column, worst first — only columns that actually have nulls |
| `es.duplicates(df, subset=None)` | Duplicate row count, % of the dataset, and a preview |
| `es.constant_and_id_cols(df)` | Columns with only one value (dead weight), and columns that are likely IDs (`nunique == len(df)`) — both are common "don't feed this to a model" traps |
| `es.inconsistent_categories(df)` | Flags values in text columns that are probably the same category typed differently — `"USA"` / `"usa "` / `"U.S.A"` — a check the bigger EDA tools skip |
| `es.outlier_report(df, method="iqr")` | Outlier count and % per numeric column, via IQR or z-score — as a table, no plot needed |

```python
es.nulls(df)
#           null_count  null_pct
# Cabin            687     77.10
# Age               177     19.87

es.inconsistent_categories(df)
# {'country': {'usa': ['USA', 'usa ', 'U.S.A'], 'uk': ['UK', 'uk']}}
```

### Summary stats

| Function | What it tells you |
|---|---|
| `es.describe_plus(df)` | `.describe()` plus null %, skew, kurtosis, and dtype in one table |
| `es.unique_report(df)` | `nunique` + a few example values per column |

### Plots (each returns the matplotlib `Figure`)

| Function | What it draws |
|---|---|
| `es.plot_numeric_distributions(df)` | Histogram + boxplot grid, one pair per numeric column |
| `es.plot_categorical_counts(df, top_n=10)` | Bar chart grid per categorical column, capped at the top N values |
| `es.plot_correlation(df)` | Masked correlation heatmap over numeric columns |
| `es.plot_target_relationship(df, target="price")` | Auto-picks boxplot/violin/scatter per feature against your target column |
| `es.plot_missing(df)` | Heatmap of where nulls occur across the whole DataFrame |

### Comparing two DataFrames

| Function | What it tells you |
|---|---|
| `es.compare_dfs(train_df, test_df)` | Shared/added/removed columns and dtype mismatches between two DataFrames — e.g. train vs. test drift |
| `es.check_merge_keys(orders_df, users_df, on="user_id")` | Before you `merge()`: dtype mismatch on the key, % of keys missing on each side, and duplicate-key counts on each side — the usual cause of a merge silently multiplying your row count |

### The one convenience function

| Function | What it does |
|---|---|
| `es.quick_report(df)` | Chains `overview` → `nulls` → `dtypes_report` → `duplicates` → `constant_and_id_cols` → a numeric-distribution plot, prints a readable summary, and returns everything as a dict. Every piece it calls also works standalone. |

## Development

```bash
git clone https://github.com/sivaraam-kr/edasnap
cd edasnap
pip install -e ".[dev]"
pytest
```

## Publishing

See [PUBLISHING.md](PUBLISHING.md) for the release checklist.

## License

MIT
