13 个版本 (8 个重大更新)
0.9.0 | 2023年5月19日 |
---|---|
0.8.0 | 2022年8月4日 |
0.7.0 | 2022年6月6日 |
0.6.2 | 2021年10月16日 |
0.6.0 | 2021年2月6日 |
#248 in 数学
每月387次下载
用于 datavzrd
125KB
2K SLoC
ndhistogram : Rust 中的多维直方图
ndhistogram 为 Rust 实现多维直方图。
该库旨在提供类似于 C++ 库 boost-histogram 的功能集,但具有纯 Rust 风格的实现。
功能包括
- 具有 1 到 21 个维度的直方图。
- 连续轴(例如,由浮点数表示)和离散轴(例如,由字符串值或枚举表示的类别)类型,它们是可组合的(例如,您可以混合离散和连续轴)。
- 灵活的 bin 值,包括任何原始数字类型或用户定义的类型。
- 直方图的未加权填充和加权填充。
- 灵活的、用户定义的轴类型。
- 稀疏直方图,以减少高 bin 计数的、大部分为空的直方图的内存占用。
目录
使用说明
将其添加到您的 Cargo.toml
[dependencies]
ndhistogram = "0.9.0"
查看 变更日志 了解版本之间的差异。请在 问题跟踪器 中报告任何错误。
快速入门
use ndhistogram::{Histogram, ndhistogram, axis::Uniform};
// create a 1D histogram with 10 equally sized bins between -5 and 5
let mut hist = ndhistogram!(Uniform::new(10, -5.0, 5.0));
// fill this histogram with a single value
hist.fill(&1.0);
// fill this histogram with weights
hist.fill_with(&2.0, 4.0);
// read the histogram values
let x1 = hist.value(&1.0);
let also_x1 = hist.value_at_index(7);
assert_eq!(x1, also_x1);
// iterate the histogram values
for item in hist.iter() {
println!("{}, {}, {}", item.index, item.bin, item.value)
}
// print the histogram to stdout
println!("{}", hist);
概述
直方图由两个组件组成:
- 坐标轴(Axes),它是一组与直方图的每个维度相对应的坐标轴(Axis)。坐标轴(Axes)和坐标轴(Axis)定义了直方图的分箱,并负责将坐标空间(例如 [x,y,z])映射到整数分箱号。
- 直方图分箱值存储。有效的分箱值类型包括任何整数和浮点数类型,以及实现了Fill、FillWith或FillWithWeighted的用户定义类型。
直方图实现
- VecHistogram:分箱值存储在Vec中。使用ndhistogram宏创建。这是大多数用例的首选实现。然而,由于即使在空分箱中也分配内存,因此这可能不适合非常高维的直方图。
- HashHistogram:分箱值存储在HashMap中。使用sparsehistogram宏创建。对于高维、大部分为空的直方图很有用,因为空分箱不占用内存。
可以通过实现Histogram特征来实现其他实现。
轴实现
- Uniform/UniformNoFlow:某些范围内的等大小分箱,可选的流入/流出分箱。
- Variable/VariableNoFlow:可变大小分箱,可选的流入/流出分箱。
- UniformCyclic/VariableCyclic:均匀和可变轴的循环或周期版本。
- Category/CategoryNoFlow:有限个离散值集合,可选的流出分箱。
通过实现Axis特征,可以实现用户定义的轴类型。
直方图 bin 值
直方图可以用以下类型的值填充
- 原始浮点数和整数数字类型。
- 实现了Fill的所有类型。
- 实现了FillWith的所有类型。
- 实现了FillWithWeighted的所有类型。
- 实现了AddAssign(因为它们也是FillWith)的所有类型。
- 实现了AddAssign和One(因为它们也是Fill)的所有类型。
此crate定义以下分箱值类型
- Sum:一个简单的分箱计数,它计算填充的次数。
- WeightedSum:与Sum类似,但带有加权填充。
- 平均值:计算其填充的值的平均值。
- 加权平均值:与平均值类似,但具有加权的填充。
通过实现 Fill、FillWith 或 FillWithWeighted 特性,可以定义用户自定义的箱值类型。
指南
自定义 bin 值类型
use ndhistogram::{Histogram, ndhistogram, axis::Uniform, value::Mean};
// Create a histogram whose bin values are i32
let mut hist = ndhistogram!(Uniform::new(10, -5.0, 5.0); i32);
hist.fill_with(&1.0, 2);
let value: Option<&i32> = hist.value(&1.0);
assert_eq!(value, Some(&2));
// More complex value types beyond primitives are available
// "Mean" calculates the average of values it is filled with
let mut hist = ndhistogram!(Uniform::new(10, -5.0, 5.0); Mean);
hist.fill_with(&1.0, 1.0);
hist.fill_with(&1.0, 3.0);
assert_eq!(hist.value(&1.0).unwrap().mean(), 2.0);
// for other examples see the documentation of Sum, WeightedSum and WeightedMean
// user defined value types are possible by implementing
// Fill, FillWith or FillWithWeighted traits
创建和使用 2D 直方图
use ndhistogram::{Histogram, ndhistogram, axis::Uniform};
// create a 2D histogram
let mut hist = ndhistogram!(Uniform::new(10, -5.0, 5.0), Uniform::new(10, -5.0, 5.0));
// fill 2D histogram
hist.fill(&(1.0, 2.0));
// read back the histogram values
let x1_y2 = hist.value(&(1.0, 2.0));
// higher dimensions are possible with additional arguments to ndhistogram
创建具有离散轴的直方图
use ndhistogram::{Histogram, ndhistogram, axis::Category};
let mut hist = ndhistogram!(Category::new(vec![0, 2, 4]));
hist.fill_with(&2, 42.0);
hist.fill_with(&1, 128.0);
assert_eq!(hist.value(&2), Some(&42.0));
assert_eq!(hist.value(&1), Some(&128.0));
assert_eq!(hist.value(&3), Some(&128.0));
// 1 and 3 give the same answer as they are both mapped to the overflow bin
// For a version with no overflow bins use CategoryNoFlow
// The Category type can be any hashable type, for example string
let mut hist = ndhistogram!(Category::new(vec!["Red", "Blue", "Green"]));
hist.fill(&"Red");
assert_eq!(hist.value(&"Red"), Some(&1.0));
创建具有可变大小 bin 的直方图
use ndhistogram::{Histogram, ndhistogram, axis::Variable};
let mut hist = ndhistogram!(Variable::new(vec![0.0, 1.0, 3.0, 6.0]));
for x in 0..6 {
hist.fill(&f64::from(x));
}
assert_eq!(hist.value(&0.0), Some(&1.0));
assert_eq!(hist.value(&1.0), Some(&2.0));
assert_eq!(hist.value(&3.0), Some(&3.0));
创建具有周期性或循环轴的直方图
use std::f64::consts::PI;
use ndhistogram::{Histogram, ndhistogram, axis::UniformCyclic};
let mut hist = ndhistogram!(UniformCyclic::<f64>::new(10, 0.0, 2.0*PI));
hist.fill(&PI);
hist.fill(&-PI);
// +pi and -pi are mapped onto the same value
assert_eq!(hist.value(&-PI), Some(&2.0));
assert_eq!(hist.value(&PI), Some(&2.0));
创建稀疏直方图
use ndhistogram::{Histogram, sparsehistogram, axis::Uniform};
// This histogram has 1e18 bins, too many to allocate with a normal histogram
let mut histogram_with_lots_of_bins = sparsehistogram!(
Uniform::new(1_000_000, -5.0, 5.0),
Uniform::new(1_000_000, -5.0, 5.0),
Uniform::new(1_000_000, -5.0, 5.0)
);
histogram_with_lots_of_bins.fill(&(1.0, 2.0, 3.0));
// read back the filled value
assert_eq!(histogram_with_lots_of_bins.value(&(1.0, 2.0, 3.0)).unwrap(), &1.0);
// unfilled bins will return None
assert!(histogram_with_lots_of_bins.value(&(0.0, 0.0, 0.0)).is_none());
合并直方图
use ndhistogram::{Histogram, ndhistogram, axis::Uniform};
let mut hist1 = ndhistogram!(Uniform::<f64>::new(10, -5.0, 5.0));
let mut hist2 = ndhistogram!(Uniform::<f64>::new(10, -5.0, 5.0));
hist1.fill_with(&0.0, 2.0);
hist2.fill_with(&0.0, 3.0);
let combined_hist = (hist1 + &hist2).expect("Axes are compatible");
并行迭代直方图 bin
use rayon::prelude::*;
use ndhistogram::{Histogram, ndhistogram, axis::Uniform};
let mut histogram = ndhistogram!(Uniform::<f64>::new(10, -5.0, 5.0));
let sum: f64 = histogram.par_iter().map(|bin| bin.value).sum();
// see also: par_iter_mut, par_values, par_values_mut.
assert_eq!(sum, 0.0);
需要启用 "rayon" 功能。
包功能标志
默认情况下,此 crate 的所有 cargo 功能都已关闭。您可以在您的 Cargo.toml
中启用以下功能
- [serde]:启用直方图序列化和反序列化支持。
- [rayon]:启用对直方图的并行迭代。
许可证
在以下任一许可证下授权:
- Apache License, Version 2.0 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
由您选择。
贡献
除非您明确说明,否则任何有意提交以包含在您的工作中的贡献,根据 Apache-2.0 许可证的定义,将如上双许可,没有任何附加条款或条件。
依赖关系
~94–590KB
~12K SLoC