pub struct Histogram {
pub edges: Vec<f64>,
pub counts: Vec<usize>,
}Expand description
An equal-width histogram over the non-missing values of a numeric column.
The bin count follows Sturges’ rule (ceil(log2(n) + 1), floored at 1).
edges.len() == counts.len() + 1; the final bin is inclusive of its upper
edge so the maximum value is never dropped.
Fields§
§edges: Vec<f64>Bin edges, ascending. Length is counts.len() + 1 (empty for an empty
column).
counts: Vec<usize>Number of values falling into each bin. Length is one less than
edges.
Implementations§
Source§impl Histogram
impl Histogram
Sourcepub fn nbins(&self) -> usize
pub fn nbins(&self) -> usize
Returns the number of bins (== counts.len()).
Examples found in repository?
examples/numeric_distribution.rs (line 63)
11fn main() -> datarust_profile::Result<()> {
12 // A synthetic column with a visible right skew: most values cluster low,
13 // one extreme value pulls the tail.
14 let m = Matrix::from_rows(vec![
15 vec![10.0],
16 vec![12.0],
17 vec![11.0],
18 vec![13.0],
19 vec![10.0],
20 vec![14.0],
21 vec![12.0],
22 vec![11.0],
23 vec![150.0], // outlier — well above the IQR fence
24 ])?;
25
26 let p = profile_matrix(&m, Some(&["reaction_ms".into()]))?;
27 let col = &p.columns[0];
28 let n = col.numeric.as_ref().expect("numeric column");
29
30 println!(
31 "Column: {} ({} rows, {} missing)\n",
32 col.name, col.count, col.missing_count
33 );
34
35 // Central tendency + spread.
36 println!(" mean = {:.2}", n.mean);
37 println!(" std = {:.2}\n", n.std);
38
39 // Five-number summary (min / Q1 / median / Q3 / max).
40 println!(" five-number summary:");
41 println!(" min = {:.1}", n.five.min);
42 println!(" Q1 = {:.1}", n.five.q1);
43 println!(" median = {:.1}", n.five.median);
44 println!(" Q3 = {:.1}", n.five.q3);
45 println!(" max = {:.1}\n", n.five.max);
46
47 // Distributional shape (v0.2).
48 // skew ≈ 0 → symmetric; large positive → right tail (our case).
49 // excess kurtosis ≈ 0 → normal-like; positive → heavy-tailed.
50 println!(" shape:");
51 println!(
52 " skewness = {:+.3} ({})",
53 n.skewness,
54 describe_skew(n.skewness)
55 );
56 println!(
57 " kurtosis = {:+.3} ({})\n",
58 n.kurtosis,
59 describe_kurtosis(n.kurtosis)
60 );
61
62 // Histogram — equal-width bins, Sturges' rule for the count.
63 println!(" histogram ({} bins):", n.histogram.nbins());
64 let max_count = n.histogram.max_count().max(1);
65 for (i, &count) in n.histogram.counts.iter().enumerate() {
66 let lo = n.histogram.edges.get(i).copied().unwrap_or(f64::NAN);
67 let hi = n.histogram.edges.get(i + 1).copied().unwrap_or(f64::NAN);
68 let bar_len = (count as f64 / max_count as f64 * 40.0).round() as usize;
69 let bar: String = "█".repeat(bar_len);
70 println!(" [{:>7.1}, {:>7.1}) {:>3} {}", lo, hi, count, bar);
71 }
72 println!();
73
74 // Outliers — values beyond the Tukey IQR fences.
75 println!(" outliers (IQR rule):");
76 println!(
77 " {} found ({:.1}% of values)\n",
78 n.outlier_count,
79 n.outlier_fraction * 100.0
80 );
81
82 Ok(())
83}Sourcepub fn max_count(&self) -> usize
pub fn max_count(&self) -> usize
Returns the count in the tallest bin, or 0 for an empty histogram.
Examples found in repository?
examples/numeric_distribution.rs (line 64)
11fn main() -> datarust_profile::Result<()> {
12 // A synthetic column with a visible right skew: most values cluster low,
13 // one extreme value pulls the tail.
14 let m = Matrix::from_rows(vec![
15 vec![10.0],
16 vec![12.0],
17 vec![11.0],
18 vec![13.0],
19 vec![10.0],
20 vec![14.0],
21 vec![12.0],
22 vec![11.0],
23 vec![150.0], // outlier — well above the IQR fence
24 ])?;
25
26 let p = profile_matrix(&m, Some(&["reaction_ms".into()]))?;
27 let col = &p.columns[0];
28 let n = col.numeric.as_ref().expect("numeric column");
29
30 println!(
31 "Column: {} ({} rows, {} missing)\n",
32 col.name, col.count, col.missing_count
33 );
34
35 // Central tendency + spread.
36 println!(" mean = {:.2}", n.mean);
37 println!(" std = {:.2}\n", n.std);
38
39 // Five-number summary (min / Q1 / median / Q3 / max).
40 println!(" five-number summary:");
41 println!(" min = {:.1}", n.five.min);
42 println!(" Q1 = {:.1}", n.five.q1);
43 println!(" median = {:.1}", n.five.median);
44 println!(" Q3 = {:.1}", n.five.q3);
45 println!(" max = {:.1}\n", n.five.max);
46
47 // Distributional shape (v0.2).
48 // skew ≈ 0 → symmetric; large positive → right tail (our case).
49 // excess kurtosis ≈ 0 → normal-like; positive → heavy-tailed.
50 println!(" shape:");
51 println!(
52 " skewness = {:+.3} ({})",
53 n.skewness,
54 describe_skew(n.skewness)
55 );
56 println!(
57 " kurtosis = {:+.3} ({})\n",
58 n.kurtosis,
59 describe_kurtosis(n.kurtosis)
60 );
61
62 // Histogram — equal-width bins, Sturges' rule for the count.
63 println!(" histogram ({} bins):", n.histogram.nbins());
64 let max_count = n.histogram.max_count().max(1);
65 for (i, &count) in n.histogram.counts.iter().enumerate() {
66 let lo = n.histogram.edges.get(i).copied().unwrap_or(f64::NAN);
67 let hi = n.histogram.edges.get(i + 1).copied().unwrap_or(f64::NAN);
68 let bar_len = (count as f64 / max_count as f64 * 40.0).round() as usize;
69 let bar: String = "█".repeat(bar_len);
70 println!(" [{:>7.1}, {:>7.1}) {:>3} {}", lo, hi, count, bar);
71 }
72 println!();
73
74 // Outliers — values beyond the Tukey IQR fences.
75 println!(" outliers (IQR rule):");
76 println!(
77 " {} found ({:.1}% of values)\n",
78 n.outlier_count,
79 n.outlier_fraction * 100.0
80 );
81
82 Ok(())
83}Trait Implementations§
impl StructuralPartialEq for Histogram
Auto Trait Implementations§
impl Freeze for Histogram
impl RefUnwindSafe for Histogram
impl Send for Histogram
impl Sync for Histogram
impl Unpin for Histogram
impl UnsafeUnpin for Histogram
impl UnwindSafe for Histogram
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more