Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Quick Start

A 60-second tour: profile a numeric matrix, read the results, and render a report. Everything here works with the default feature set — no serde required for the HTML report.

Install

[dependencies]
datarust = "0.6"
datarust-profile = "0.3"

For JSON output, enable the serde feature (this also pulls in datarust/serde):

[dependencies]
datarust-profile = { version = "0.3", features = ["serde"] }

Profile a numeric matrix

profile_matrix takes a datarust::Matrix and returns a DatasetProfile. Missing values are encoded as NaN and excluded from every statistic.

#![allow(unused)]
fn main() {
use datarust::Matrix;
use datarust_profile::profile_matrix;

let m = Matrix::from_rows(vec![
    vec![1.0, 10.0],
    vec![2.0, 20.0],
    vec![3.0, 30.0],
    vec![4.0, 40.0],
    vec![5.0, f64::NAN], // missing in column 1
])?;

let p = profile_matrix(&m, Some(&["x".into(), "y".into()]))?;
}

Column names are optional — pass None and they default to x0..x{n-1}.

Read the numeric profile

Each column carries a NumericStats block: central tendency, spread, shape, and outliers.

#![allow(unused)]
fn main() {
let col = &p.columns[0];
let n = col.numeric.as_ref().unwrap();

println!("mean={:.2}  std={:.2}", n.mean, n.std);
println!("min={:.1}  Q1={:.1}  median={:.1}  Q3={:.1}  max={:.1}",
    n.five.min, n.five.q1, n.five.median, n.five.q3, n.five.max);

// v0.2: distributional shape.
println!("skewness={:.3}  kurtosis={:.3}", n.skewness, n.kurtosis);
println!("histogram bins: {} (counts: {:?})", n.histogram.nbins(), n.histogram.counts);
println!("outliers: {} ({:.1}%)", n.outlier_count, n.outlier_fraction * 100.0);
}

Skewness near zero means a symmetric column; large positive values indicate a right tail. Excess kurtosis near zero matches a normal distribution; positive values indicate heavier tails, negative values a flatter peak.

Pairwise relationships & target leakage

v0.3 computes pairwise column relationships: Pearson correlation for numerics, Cramér’s V for categoricals, and point-biserial correlation for binary categorical ⇄ numeric pairs. You can also specify a target column with profile_table_with_target.

#![allow(unused)]
fn main() {
use datarust_profile::profile_table_with_target;

let p = profile_table_with_target(
    Some(&numeric_matrix),
    Some(&categorical_matrix),
    &["age".into(), "income".into(), "churn".into()],
    "churn",
)?;

if let Some(rels) = &p.relationships {
    if let Some(pearson) = &rels.pearson {
        println!("Pearson correlation between {} and {}: {:.3}",
            pearson.labels[0], pearson.labels[1], pearson.values[0][1]);
    }
}
}

Profile categorical data

profile_str_matrix infers each column’s type: if every non-empty cell parses as f64 it is treated as numeric, otherwise categorical.

#![allow(unused)]
fn main() {
use datarust::StrMatrix;
use datarust_profile::profile_str_matrix;

let s = StrMatrix::from_strings(vec![
    vec!["25", "Istanbul", "basic"],
    vec!["40", "Ankara", "premium"],
    vec!["31", "Izmir", "basic"],
])?;

let p = profile_str_matrix(&s, Some(&["age".into(), "city".into(), "tier".into()]))?;

let city = &p.columns[1];
let c = city.categorical.as_ref().unwrap();
println!("{} unique values; top is '{}' ({} rows, {:.0}% of data)",
    c.unique, c.top, c.freq, c.imbalance_ratio * 100.0);
}

imbalance_ratio is the share of the most frequent value: 1.0 means a single value dominates the whole column — a data-quality smell.

Mixed tables

profile_table takes a numeric block and a categorical block side by side, sharing the same row count. This is the natural fit for real-world CSV data.

#![allow(unused)]
fn main() {
use datarust_profile::profile_table;

let p = profile_table(
    Some(&numeric_matrix),
    Some(&categorical_str_matrix),
    &["age".into(), "income".into(), "city".into(), "tier".into()],
)?;
}

Render a report

The HTML renderer produces a single self-contained document — inline CSS, no JavaScript, no external assets, now with correlation heatmaps. The JSON renderer needs the serde feature.

#![allow(unused)]
fn main() {
use datarust_profile::report;

// Always available:
let html = report::to_html(&p);
std::fs::write("profile.html", html)?;

#[cfg(feature = "serde")]
{
    let json = report::to_json(&report::JsonReport::from_profile(&p))?;
    std::fs::write("profile.json", json)?;
}
}

The HTML report lays columns out as a responsive card grid and adds a Relationships section with interactive-feel correlation heatmaps (Pearson & Cramér’s V) and point-biserial tables.

Next steps

  • The Profiling Guide covers numeric, categorical, relationships, and the full set of data-quality checks.
  • The API reference documents every type and function.