lgtm
This commit is contained in:
parent
f7e0814a38
commit
fd2860070a
55 changed files with 4084 additions and 186 deletions
47
server-rs/src/data/area_crime_averages.rs
Normal file
47
server-rs/src/data/area_crime_averages.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
//! 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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue