polars_compute/rolling/
mod.rs1mod min_max;
2pub mod moment;
3pub mod no_nulls;
4pub mod nulls;
5pub mod quantile_filter;
6pub(super) mod window;
7use std::hash::Hash;
8use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
9
10use arrow::array::{ArrayRef, PrimitiveArray};
11use arrow::bitmap::{Bitmap, MutableBitmap};
12use arrow::types::NativeType;
13use num_traits::{Bounded, Float, NumCast, One, Zero};
14use polars_utils::float::IsFloat;
15#[cfg(feature = "serde")]
16use serde::{Deserialize, Serialize};
17use strum_macros::IntoStaticStr;
18use window::*;
19
20type Start = usize;
21type End = usize;
22type Idx = usize;
23type WindowSize = usize;
24type Len = usize;
25
26#[derive(Clone, Copy, PartialEq, Eq, Debug, Default, Hash, IntoStaticStr)]
27#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
28#[strum(serialize_all = "snake_case")]
29pub enum QuantileMethod {
30 #[default]
31 Nearest,
32 Lower,
33 Higher,
34 Midpoint,
35 Linear,
36 Equiprobable,
37}
38
39#[deprecated(note = "use QuantileMethod instead")]
40pub type QuantileInterpolOptions = QuantileMethod;
41
42#[derive(Clone, Copy, Debug, PartialEq, Hash)]
43#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
44pub enum RollingFnParams {
45 Quantile(RollingQuantileParams),
46 Var(RollingVarParams),
47 Skew { bias: bool },
48 Kurtosis { fisher: bool, bias: bool },
49}
50
51fn det_offsets(i: Idx, window_size: WindowSize, _len: Len) -> (usize, usize) {
52 (i.saturating_sub(window_size - 1), i + 1)
53}
54fn det_offsets_center(i: Idx, window_size: WindowSize, len: Len) -> (usize, usize) {
55 let right_window = window_size.div_ceil(2);
56 (
57 i.saturating_sub(window_size - right_window),
58 std::cmp::min(len, i + right_window),
59 )
60}
61
62fn create_validity<Fo>(
63 min_periods: usize,
64 len: usize,
65 window_size: usize,
66 det_offsets_fn: Fo,
67) -> Option<MutableBitmap>
68where
69 Fo: Fn(Idx, WindowSize, Len) -> (Start, End),
70{
71 if min_periods > 1 {
72 let mut validity = MutableBitmap::with_capacity(len);
73 validity.extend_constant(len, true);
74
75 for i in 0..len {
79 let (start, end) = det_offsets_fn(i, window_size, len);
80 if (end - start) < min_periods {
81 validity.set(i, false)
82 } else {
83 break;
84 }
85 }
86 for i in (0..len).rev() {
88 let (start, end) = det_offsets_fn(i, window_size, len);
89 if (end - start) < min_periods {
90 validity.set(i, false)
91 } else {
92 break;
93 }
94 }
95
96 Some(validity)
97 } else {
98 None
99 }
100}
101
102#[derive(Clone, Copy, Debug, PartialEq, Hash)]
104#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
105pub struct RollingVarParams {
106 pub ddof: u8,
107}
108
109#[derive(Clone, Copy, Debug, PartialEq)]
110#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
111pub struct RollingQuantileParams {
112 pub prob: f64,
113 pub method: QuantileMethod,
114}
115
116impl Hash for RollingQuantileParams {
117 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
118 self.prob.to_bits().hash(state);
120 self.method.hash(state);
121 }
122}