reducers
Reduction functions + Rust(rs), shortname rd.
Rust-backed reduction functions for NumPy arrays - plain (numpy-like) and NaN-aware.
- Full documentation: https://ysbach.github.io/reducers/
- Rust API reference: https://docs.rs/reducers
The Goal of this toy project was:
- much faster than numpy in many use cases,
- much faster than bottleneck in many use cases, and
- especially maximum performance for median and variance calculations, which are often bottlenecks in data processing pipelines.
reducers might be slower than numpy or bottleneck for small arrays. However, the most time-consuming reductions like large arrays or deep stacks, median, percentile or quantile, var and std are frequently several times (>100 times for nanpercentiles) faster than numpy and bottleneck.
Install
For Rust crate use:
[]
= "0.2"
After Installation
Run the autotuner once on your machine where reducers will run:
It saves parallel-grain settings for that CPU and workload profile. Future
import reducers calls apply those settings automatically. The built-in
defaults are still valid; use python -m reducers.autotuner --reset to remove
the saved tuning file and return to them.
=
# nan: plain reducers propagate NaN/inf
# inf: skip NaN, keep inf
# finite-only
# one fused 1-D scan for nanmin + nanmax
Axis reductions cover the layouts this package optimizes:
=
=
=
# stack reduction -> shape (256, 256)
# contiguous trailing-axis reduction
- For
[nan]varand[nan]std,return_mean=Truereturns the already-computed mean with the variance or standard deviation to avoid duplicate work when both are needed. [nan]sum(a, weights=w)can do similar:return_sum_weights=Trueandreturn_unweighted_sum=Trueexpose quantities already available during the fused weighted scan, avoiding separatesum(a * w),sum(w), orsum(a)passes when a caller needs them together.
, =
, =
, =
, , =
Dual use: the kernel modules are pure Rust (no PyO3/NumPy) and usable as a crate;
the reducers._core Python extension is built with the extension-module
feature.
Current limits
-
axismay beNone(default, whole-array),0or-1(identical toa.ndim - 1); other axes raiseNotImplementedError. This keeps hidden transpose/copy costs out of the API and lets the Rust kernels specialize for the supported layouts. -
NumPy-like subset: There are many unsupported parameters like
out,keepdims,where,dtype, or percentilemethod(linear only). Adding them will not likely be considered unless there is a strong use case, as they add complexity and maintenance burden. The main focus is on the core reduction logic and, more importantly, performance.
See the documentation for detailed API semantics, performance notes, axis behavior, and release wheels: https://ysbach.github.io/reducers/.