Drop labels whose frequency is below `min_pct`.
(
events: &[(NaiveDateTime, f64, f64, i8, Option<f64>)],
min_pct: f64,
)
| 241 | |
| 242 | /// Drop labels whose frequency is below `min_pct`. |
| 243 | pub fn drop_labels( |
| 244 | events: &[(NaiveDateTime, f64, f64, i8, Option<f64>)], |
| 245 | min_pct: f64, |
| 246 | ) -> Vec<(NaiveDateTime, f64, f64, i8, Option<f64>)> { |
| 247 | let mut filtered: Vec<_> = events.to_vec(); |
| 248 | loop { |
| 249 | let mut counts: std::collections::HashMap<i8, usize> = std::collections::HashMap::new(); |
| 250 | for (_, _, _, bin, _) in &filtered { |
| 251 | *counts.entry(*bin).or_default() += 1; |
| 252 | } |
| 253 | let total = filtered.len() as f64; |
| 254 | let mut min_label: Option<(i8, f64)> = None; |
| 255 | for (label, count) in &counts { |
| 256 | let pct = *count as f64 / total; |
| 257 | if min_label.map_or(true, |(_, p)| pct < p) { |
| 258 | min_label = Some((*label, pct)); |
| 259 | } |
| 260 | } |
| 261 | if let Some((label, pct)) = min_label { |
| 262 | if pct <= min_pct && counts.len() >= 3 { |
| 263 | filtered.retain(|(_, _, _, b, _)| *b != label); |
| 264 | continue; |
| 265 | } |
| 266 | } |
| 267 | break; |
| 268 | } |
| 269 | filtered |
| 270 | } |