Path: blob/main/crates/polars-compute/src/rolling/mod.rs
6939 views
mod min_max;1pub mod moment;2pub mod no_nulls;3pub mod nulls;4pub mod quantile_filter;5pub(super) mod window;6use std::hash::Hash;7use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};89use arrow::array::{ArrayRef, PrimitiveArray};10use arrow::bitmap::{Bitmap, MutableBitmap};11use arrow::types::NativeType;12use num_traits::{Bounded, Float, NumCast, One, Zero};13use polars_utils::float::IsFloat;14#[cfg(feature = "serde")]15use serde::{Deserialize, Serialize};16use strum_macros::IntoStaticStr;17use window::*;1819type Start = usize;20type End = usize;21type Idx = usize;22type WindowSize = usize;23type Len = usize;2425#[derive(Clone, Copy, PartialEq, Eq, Debug, Default, Hash, IntoStaticStr)]26#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]27#[cfg_attr(feature = "dsl-schema", derive(schemars::JsonSchema))]28#[strum(serialize_all = "snake_case")]29pub enum QuantileMethod {30#[default]31Nearest,32Lower,33Higher,34Midpoint,35Linear,36Equiprobable,37}3839#[deprecated(note = "use QuantileMethod instead")]40pub type QuantileInterpolOptions = QuantileMethod;4142#[derive(Clone, Copy, Debug, PartialEq, Hash)]43#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]44#[cfg_attr(feature = "dsl-schema", derive(schemars::JsonSchema))]45pub enum RollingFnParams {46Quantile(RollingQuantileParams),47Var(RollingVarParams),48Skew { bias: bool },49Kurtosis { fisher: bool, bias: bool },50}5152fn det_offsets(i: Idx, window_size: WindowSize, _len: Len) -> (usize, usize) {53(i.saturating_sub(window_size - 1), i + 1)54}55fn det_offsets_center(i: Idx, window_size: WindowSize, len: Len) -> (usize, usize) {56let right_window = window_size.div_ceil(2);57(58i.saturating_sub(window_size - right_window),59std::cmp::min(len, i + right_window),60)61}6263fn create_validity<Fo>(64min_periods: usize,65len: usize,66window_size: usize,67det_offsets_fn: Fo,68) -> Option<MutableBitmap>69where70Fo: Fn(Idx, WindowSize, Len) -> (Start, End),71{72if min_periods > 1 {73let mut validity = MutableBitmap::with_capacity(len);74validity.extend_constant(len, true);7576// Set the null values at the boundaries7778// Head.79for i in 0..len {80let (start, end) = det_offsets_fn(i, window_size, len);81if (end - start) < min_periods {82validity.set(i, false)83} else {84break;85}86}87// Tail.88for i in (0..len).rev() {89let (start, end) = det_offsets_fn(i, window_size, len);90if (end - start) < min_periods {91validity.set(i, false)92} else {93break;94}95}9697Some(validity)98} else {99None100}101}102103// Parameters allowed for rolling operations.104#[derive(Clone, Copy, Debug, PartialEq, Hash)]105#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]106#[cfg_attr(feature = "dsl-schema", derive(schemars::JsonSchema))]107pub struct RollingVarParams {108pub ddof: u8,109}110111#[derive(Clone, Copy, Debug, PartialEq)]112#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]113#[cfg_attr(feature = "dsl-schema", derive(schemars::JsonSchema))]114pub struct RollingQuantileParams {115pub prob: f64,116pub method: QuantileMethod,117}118119impl Hash for RollingQuantileParams {120fn hash<H: std::hash::Hasher>(&self, state: &mut H) {121// Will not be NaN, so hash + eq symmetry will hold.122self.prob.to_bits().hash(state);123self.method.hash(state);124}125}126127128