Metadata-Version: 2.4
Name: robustats-py
Version: 0.2.0
Summary: Robust statistics for NumPy: replaces mean with median for outlier-resistant analysis
License-Expression: MIT
Project-URL: Homepage, https://github.com/Vishnusai17/robustats
Project-URL: Repository, https://github.com/Vishnusai17/robustats
Project-URL: Bug Tracker, https://github.com/Vishnusai17/robustats/issues
Keywords: statistics,numpy,median,robust,outliers,data-science
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.21
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Dynamic: license-file

# robustats

> **Robust statistics for NumPy** — replaces `mean` with `median` for outlier-resistant data analysis.

[![PyPI](https://img.shields.io/pypi/v/robustats)](https://pypi.org/project/robustats/)
[![Python](https://img.shields.io/badge/python-3.8%2B-blue)]()
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

## Why?

NumPy's `np.mean` is sensitive to outliers. One extreme value can distort your entire analysis. `robustats` swaps `mean` with `median` by default — a far more robust estimator — while keeping the same familiar API.

```python
data = [1, 2, 3, 4, 1000]

np.mean(data)      # 202.0  ← distorted by outlier
rs.mean(data)      #   3.0  ← robust, ignores outlier
```

## Installation

```bash
pip install robustats
```

## Quick Start

```python
import numpy as np
import robustats as rs

data = [1, 2, 3, 4, 1000]

# Drop-in replacements
rs.mean(data)               # 3.0    (median, robust)
rs.nanmean(data)            # 3.0    (nanmedian, robust)
rs.std(data)                # 1.4826 (MAD-based, robust)
rs.var(data)                # 2.198  (MAD², robust)
rs.mad(data)                # 1.4826 (Median Absolute Deviation)

# Use arithmetic mean explicitly
rs.mean(data, use_median=False)    # 202.0

# Weighted median
rs.average(data, weights=[1,1,1,1,10])   # 5.0
```

## Context Manager — patch `np.mean` temporarily

```python
with rs.robust_mode():
    np.mean(data)     # 3.0 inside the block
np.mean(data)         # 202.0 restored after the block
```

## Global Patch — replace `np.mean` everywhere

```python
rs.patch_numpy()
np.mean(data)     # 3.0  (global replacement)

rs.unpatch_numpy()
np.mean(data)     # 202.0 (restored)
```

## API Reference

| Function | Description |
|---|---|
| `rs.mean(a, axis, use_median=True)` | Median (or mean) of array |
| `rs.nanmean(a, axis, use_median=True)` | Nanmedian (or nanmean) |
| `rs.std(a, axis, use_mad=True)` | MAD-based std (or numpy std) |
| `rs.var(a, axis, use_mad=True)` | MAD²-based var (or numpy var) |
| `rs.mad(a, axis, scale=1.4826)` | Median Absolute Deviation |
| `rs.average(a, weights, use_median=True)` | Weighted median (or average) |
| `rs.robust_mode()` | Context manager patching `np.mean` |
| `rs.patch_numpy()` | Globally replace `np.mean` / `np.nanmean` |
| `rs.unpatch_numpy()` | Restore originals |

## When to use robustats

- Your data may have **outliers** or measurement errors
- You're doing **exploratory data analysis** on real-world datasets
- You need a **quick drop-in** without changing all your `np.mean` calls (`robust_mode` context)
- You want **robust standard deviation** via MAD instead of classical std

## License

MIT
