在Rust中计算向量的百分比变化有什么简便实现方法?
Rust 标准库没有内置向量百分比变化的计算方法,但完全不需要手动写for循环遍历,可以通过迭代器组合实现,还可以通过扩展 trait 实现你期望的 .pct_change() 调用形式。
扩展trait实现(匹配你期望的调用方式)
// 定义扩展trait trait PctChangeExt { fn pct_change(&self) -> Vec<f64>; } // 为元素为f64的Vec实现扩展trait impl PctChangeExt for Vec<f64> { fn pct_change(&self) -> Vec<f64> { if self.is_empty() { return Vec::new(); } // 第一个元素填NaN,后续遍历相邻窗口计算变化率 std::iter::once(f64::NAN) .chain(self.windows(2).map(|window| (window[1] - window[0]) / window[0])) .collect() } } fn main() { let vec1 = vec![90.0, 91.0, 85.0]; let pct_change = vec1.pct_change(); // 输出:[NaN, 0.011111111111111112, -0.06593406593406594] println!("{:?}", pct_change); }
如果需要保留6位小数的结果,可以在map的时候做四舍五入处理:
.map(|window| ((window[1] - window[0]) / window[0] * 1e6).round() / 1e6)
就能得到你预期的[NaN, 0.011111, -0.065934]输出。
无需扩展trait的一行实现
如果不想额外定义trait,直接通过迭代器组合就能完成计算,不需要手动写for循环:
let vec1 = vec![90.0, 91.0, 85.0]; let pct_change: Vec<f64> = std::iter::once(f64::NAN) .chain(vec1.windows(2).map(|w| (w[1] - w[0]) / w[0])) .collect();
注意事项
- 若前序元素为0,计算会得到
inf/-inf,如果需要自定义除零逻辑,可以在map中添加判断:.map(|window| if window[0] == 0.0 { f64::NAN } else { (window[1] - window[0]) / window[0] }) - 上述实现默认适用于
f64类型向量,如果需要适配f32,只需要将trait实现调整为对应类型即可。
内容的提问来源于stack exchange,提问作者AlgoQ
相关产品推荐
相关产品推荐

