Skip to main content

Ruddy

PyPI PyVersions Tests License

Ruddy is a Python library for statistical exploratory data analysis. It works on tables and on numerical feature spaces such as embeddings or descriptor matrices, as long as each row belongs to an identifiable observation. Results come back as Polars tables that carry sample counts, diagnostics and the parameters used, so you can filter them, export them or plot them.

Ruddy doesn't know about any particular domain and doesn't compute features. You bring the data or the representation, and Ruddy analyzes it. It also has no plotting code, but you can use your prefered library for visualizations. See example notebooks for more comprehensive examples.

Installation

Ruddy supports Python 3.11 to 3.14.

python -m pip install ruddy

For optional UMAP support:

python -m pip install "ruddy[manifold]"

For development setup with uv, see DEVELOPMENT.md.

Analyze a table

import polars as pl
from ruddy import TabularDataset, analyze_univariate, analyze_bivariate

frame = pl.DataFrame({
    "id": ["s1", "s2", "s3", "s4", "s5", "s6"],
    "activity": [1.2, 2.4, 1.8, 3.1, 2.9, 4.2],
    "length": [10.0, 14.0, 12.0, 17.0, 15.0, 20.0],
    "family": ["A", "A", "A", "B", "B", "B"],
})
dataset = TabularDataset(
    frame,
    id_column="id",
    role_overrides={
        "activity": "response",
        "family": "factor",
        "length": "covariate",
    },
)

univariate = analyze_univariate(dataset)
bivariate = analyze_bivariate(dataset)
print(univariate.numeric_statistics)
print(bivariate.correlations)

To read files, use pl.read_csv(...) or pl.read_parquet(...). pandas DataFrames work too. A column's role doesn't depend on its dtype, so a batch stored as integers can still be declared a categorical factor. The data contracts guide explains how observation IDs are checked and aligned.

Analyze a feature space

from ruddy import FeatureMatrix, analyze_pca

features = FeatureMatrix(
    dataset.frame.select("activity", "length"),
    observation_ids=dataset.observation_ids,
)
pca = analyze_pca(features, n_components=2, scaling="standard")
print(pca.scores)
print(pca.variance)

FeatureMatrix also takes NumPy arrays and SciPy sparse matrices. Not every method accepts sparse input, and Ruddy raises an error rather than densify it behind your back. To compare two feature spaces, give both of them observation IDs:

# Given two FeatureMatrix objects named space_a and space_b:
from ruddy import analyze_representation_similarity

comparison = analyze_representation_similarity(
    space_a,
    space_b,
    alignment="strict",
    cca_components=2,
    random_state=42,
)
print(comparison.cka)
print(comparison.mantel)

The method reference lists every analysis with its assumptions and how to read its output. Besides the ones above, Ruddy has group comparisons, bootstrap intervals, factorial and mixed-effects models, PERMANOVA, compositional data, Bayesian summaries and anomaly flags.

Run several analyses

from ruddy import AnalysisConfig, analyze

result = analyze(
    dataset,
    config=AnalysisConfig(
        enabled_blocks=("profiling", "univariate", "groups", "outliers"),
        responses=("activity",),
        groups=("family",),
        random_state=42,
    ),
)
print(result.summary())

By default only profiling and univariate analysis run. The unified analysis guide covers the other blocks and their parameters.

Command line

ruddy --help
ruddy analyze bivariate data.csv \
  --id-column id \
  --factor family \
  --output-dir results

The commands are grouped under inspect, analyze, model and project. ruddy pipeline runs several blocks in one go, but only the ones you select. The CLI reference documents every option and the files each command writes.

Design principles

Ruddy tries hard not to make decisions for you:

  • Scaling and dimensionality reduction happen only when you ask for them. Missing values aren't imputed, and a string that looks like a number stays a string.
  • Each analysis reports which observations it used. Excluding a row never deletes it from your data.
  • A diagnostic never swaps the test you asked for. If a normality check fails, you still get the test you requested, with the diagnostic next to it.
  • A rank-deficient problem is reported as such, not quietly regularized.
  • Outliers are flagged and left alone.
  • Data and annotations are matched by observation ID, never by row position.
  • Every result records its parameters, input sizes, random seed and the Ruddy version that produced it.

Because of this, read status and reason next to every estimate. ok means the quantity was estimated. degenerate means the data can't support it, for example a constant column in a correlation. skipped means a requirement wasn't met. Missing values in result tables are Polars nulls, not NaN. See results and provenance for how to read and export results.

Documentation and examples

The documentation index links all the guides. There are also 13 example notebooks written in marimo. To open one:

uv sync --all-extras --group examples
uv run marimo edit examples/01_profiling_univariate.py

Citing and license

If you use Ruddy in published work, please cite it using CITATION.cff, or the "Cite this repository" button on GitHub. Ruddy is released under the MIT license.

Metadata

Release files for ruddy 0.1.0

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

Source distribution (sdist)

Source distribution for ruddy 0.1.0
File Size Uploaded Provenance Actions
ruddy-0.1.0.tar.gz 139.8 kB With provenance Details for ruddy-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for ruddy 0.1.0
File Interpreter ABI Platform Actions
ruddy-0.1.0-py3-none-any.whl Python 3 none any Details for ruddy-0.1.0-py3-none-any.whl

Total release size: 342.4 kB

Release files / ruddy-0.1.0.tar.gz

Download URL ruddy-0.1.0.tar.gz
Size 139.8 kB
Tags Source
SHA-256 checksum
How to use checksums
eefdef9ca8fde45e723f0e45d38a6599a912a7beb939f2e6f39a8696dda3bf3f
BLAKE2b-256 checksum
How to use checksums
a44cc7d35816d51bea6b2d8230645e3001f8d5c898ba5e6ce9c93b7707a13ced
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / ruddy-0.1.0-py3-none-any.whl

Download URL ruddy-0.1.0-py3-none-any.whl
Size 202.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
52f5ae554f425706b1937d854ad6a95d4b14c4b4e5fae38ecd65ceb81790d81e
BLAKE2b-256 checksum
How to use checksums
1b15710d23925624e439aec3fd191133aed97e2a2c3e1e4ac8e42d51979c4b1f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Security for ruddy 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for ruddy-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

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