47 lines
2.2 KiB
Rust
47 lines
2.2 KiB
Rust
//! Precomputed per-outcode and per-postcode-sector average crime rates.
|
|
//!
|
|
//! The right pane shows each crime metric's national average (the global
|
|
//! feature-histogram mean). To let users see how an area compares with its
|
|
//! immediate surroundings, we also precompute the mean headline crime rate
|
|
//! (`"X (avg/yr)"`) across every property in the selection's outcode (e.g.
|
|
//! `"E14"`) and postcode sector (e.g. `"E14 2"`).
|
|
//!
|
|
//! Crime figures are constant within a postcode (the pipeline merges them on
|
|
//! the postcode key), so each postcode's value is read once — from its first
|
|
//! row — and property-weighted by the postcode's row count. That keeps these
|
|
//! averages on the same property-weighted basis as the national average, so the
|
|
//! four numbers (this area / sector / outcode / nation) are directly comparable.
|
|
|
|
use rustc_hash::FxHashMap;
|
|
|
|
/// Crime-feature name suffix that marks an annualised headline-rate column
|
|
/// (e.g. `"Burglary (avg/yr)"`). Stripped to derive the bare type name.
|
|
pub const AVG_YR_SUFFIX: &str = " (avg/yr)";
|
|
|
|
pub struct AreaCrimeAverages {
|
|
/// Bare crime-type names (suffix stripped, e.g. `"Burglary"`), index-aligned
|
|
/// with the per-area mean vectors. Matches `CrimeYearStats.name`.
|
|
pub crime_types: Vec<String>,
|
|
/// National mean headline rate per crime type (index-aligned with
|
|
/// `crime_types`). An EXACT property-weighted mean over every postcode, so it
|
|
/// shares a basis with `by_outcode`/`by_sector` and the per-selection mean —
|
|
/// unlike the histogram-bin national average, which is biased upward for the
|
|
/// right-skewed crime densities. `NaN` where no postcode has data.
|
|
pub national: Vec<f32>,
|
|
/// Outcode (e.g. `"E14"`) → mean headline rate per crime type. `NaN` where
|
|
/// the outcode has no data for that type.
|
|
pub by_outcode: FxHashMap<String, Vec<f32>>,
|
|
/// Postcode sector (e.g. `"E14 2"`) → mean headline rate per crime type.
|
|
pub by_sector: FxHashMap<String, Vec<f32>>,
|
|
}
|
|
|
|
impl AreaCrimeAverages {
|
|
pub fn empty() -> Self {
|
|
Self {
|
|
crime_types: Vec::new(),
|
|
national: Vec::new(),
|
|
by_outcode: FxHashMap::default(),
|
|
by_sector: FxHashMap::default(),
|
|
}
|
|
}
|
|
}
|