polars_core/chunked_array/ops/sort/
options.rs

1#[cfg(feature = "serde-lazy")]
2use serde::{Deserialize, Serialize};
3pub use slice::*;
4
5use crate::prelude::*;
6
7/// Options for single series sorting.
8///
9/// Indicating the order of sorting, nulls position, multithreading, and maintaining order.
10///
11/// # Example
12///
13/// ```
14/// # use polars_core::prelude::*;
15/// let s = Series::new("a".into(), [Some(5), Some(2), Some(3), Some(4), None].as_ref());
16/// let sorted = s
17///     .sort(
18///         SortOptions::default()
19///             .with_order_descending(true)
20///             .with_nulls_last(true)
21///             .with_multithreaded(false),
22///     )
23///     .unwrap();
24/// assert_eq!(
25///     sorted,
26///     Series::new("a".into(), [Some(5), Some(4), Some(3), Some(2), None].as_ref())
27/// );
28/// ```
29#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
30#[cfg_attr(feature = "serde-lazy", derive(Serialize, Deserialize))]
31pub struct SortOptions {
32    /// If true sort in descending order.
33    /// Default `false`.
34    pub descending: bool,
35    /// Whether place null values last.
36    /// Default `false`.
37    pub nulls_last: bool,
38    /// If true sort in multiple threads.
39    /// Default `true`.
40    pub multithreaded: bool,
41    /// If true maintain the order of equal elements.
42    /// Default `false`.
43    pub maintain_order: bool,
44    /// Limit a sort output, this is for optimization purposes and might be ignored.
45    pub limit: Option<IdxSize>,
46}
47
48/// Sort options for multi-series sorting.
49///
50/// Indicating the order of sorting, nulls position, multithreading, and maintaining order.
51///
52/// # Example
53/// ```
54/// # use polars_core::prelude::*;
55///
56/// # fn main() -> PolarsResult<()> {
57/// let df = df! {
58///     "a" => [Some(1), Some(2), None, Some(4), None],
59///     "b" => [Some(5), None, Some(3), Some(2), Some(1)]
60/// }?;
61///
62/// let out = df
63///     .sort(
64///         ["a", "b"],
65///         SortMultipleOptions::default()
66///             .with_maintain_order(true)
67///             .with_multithreaded(false)
68///             .with_order_descending_multi([false, true])
69///             .with_nulls_last(true),
70///     )?;
71///
72/// let expected = df! {
73///     "a" => [Some(1), Some(2), Some(4), None, None],
74///     "b" => [Some(5), None, Some(2), Some(3), Some(1)]
75/// }?;
76///
77/// assert_eq!(out, expected);
78///
79/// # Ok(())
80/// # }
81#[derive(Clone, Debug, Eq, PartialEq, Hash)]
82#[cfg_attr(feature = "serde-lazy", derive(Serialize, Deserialize))]
83pub struct SortMultipleOptions {
84    /// Order of the columns. Default all `false``.
85    ///
86    /// If only one value is given, it will broadcast to all columns.
87    ///
88    /// Use [`SortMultipleOptions::with_order_descending_multi`]
89    /// or [`SortMultipleOptions::with_order_descending`] to modify.
90    ///
91    /// # Safety
92    ///
93    /// Len must match the number of columns, or equal 1.
94    pub descending: Vec<bool>,
95    /// Whether place null values last. Default `false`.
96    pub nulls_last: Vec<bool>,
97    /// Whether sort in multiple threads. Default `true`.
98    pub multithreaded: bool,
99    /// Whether maintain the order of equal elements. Default `false`.
100    pub maintain_order: bool,
101    /// Limit a sort output, this is for optimization purposes and might be ignored.
102    pub limit: Option<IdxSize>,
103}
104
105impl Default for SortOptions {
106    fn default() -> Self {
107        Self {
108            descending: false,
109            nulls_last: false,
110            multithreaded: true,
111            maintain_order: false,
112            limit: None,
113        }
114    }
115}
116
117impl Default for SortMultipleOptions {
118    fn default() -> Self {
119        Self {
120            descending: vec![false],
121            nulls_last: vec![false],
122            multithreaded: true,
123            maintain_order: false,
124            limit: None,
125        }
126    }
127}
128
129impl SortMultipleOptions {
130    /// Create `SortMultipleOptions` with default values.
131    pub fn new() -> Self {
132        Self::default()
133    }
134
135    /// Specify order for each column. Defaults all `false`.
136    ///
137    /// # Safety
138    ///
139    /// Len must match the number of columns, or be equal to 1.
140    pub fn with_order_descending_multi(
141        mut self,
142        descending: impl IntoIterator<Item = bool>,
143    ) -> Self {
144        self.descending = descending.into_iter().collect();
145        self
146    }
147
148    /// Sort order for all columns. Default `false` which is ascending.
149    pub fn with_order_descending(mut self, descending: bool) -> Self {
150        self.descending = vec![descending];
151        self
152    }
153
154    /// Specify whether to place nulls last, per-column. Defaults all `false`.
155    ///
156    /// # Safety
157    ///
158    /// Len must match the number of columns, or be equal to 1.
159    pub fn with_nulls_last_multi(mut self, nulls_last: impl IntoIterator<Item = bool>) -> Self {
160        self.nulls_last = nulls_last.into_iter().collect();
161        self
162    }
163
164    /// Whether to place null values last. Default `false`.
165    pub fn with_nulls_last(mut self, enabled: bool) -> Self {
166        self.nulls_last = vec![enabled];
167        self
168    }
169
170    /// Whether to sort in multiple threads. Default `true`.
171    pub fn with_multithreaded(mut self, enabled: bool) -> Self {
172        self.multithreaded = enabled;
173        self
174    }
175
176    /// Whether to maintain the order of equal elements. Default `false`.
177    pub fn with_maintain_order(mut self, enabled: bool) -> Self {
178        self.maintain_order = enabled;
179        self
180    }
181
182    /// Reverse the order of sorting for each column.
183    pub fn with_order_reversed(mut self) -> Self {
184        self.descending.iter_mut().for_each(|x| *x = !*x);
185        self
186    }
187}
188
189impl SortOptions {
190    /// Create `SortOptions` with default values.
191    pub fn new() -> Self {
192        Self::default()
193    }
194
195    /// Specify sorting order for the column. Default `false`.
196    pub fn with_order_descending(mut self, enabled: bool) -> Self {
197        self.descending = enabled;
198        self
199    }
200
201    /// Whether place null values last. Default `false`.
202    pub fn with_nulls_last(mut self, enabled: bool) -> Self {
203        self.nulls_last = enabled;
204        self
205    }
206
207    /// Whether sort in multiple threads. Default `true`.
208    pub fn with_multithreaded(mut self, enabled: bool) -> Self {
209        self.multithreaded = enabled;
210        self
211    }
212
213    /// Whether maintain the order of equal elements. Default `false`.
214    pub fn with_maintain_order(mut self, enabled: bool) -> Self {
215        self.maintain_order = enabled;
216        self
217    }
218
219    /// Reverse the order of sorting.
220    pub fn with_order_reversed(mut self) -> Self {
221        self.descending = !self.descending;
222        self
223    }
224}
225
226impl From<&SortOptions> for SortMultipleOptions {
227    fn from(value: &SortOptions) -> Self {
228        SortMultipleOptions {
229            descending: vec![value.descending],
230            nulls_last: vec![value.nulls_last],
231            multithreaded: value.multithreaded,
232            maintain_order: value.maintain_order,
233            limit: value.limit,
234        }
235    }
236}
237
238impl From<&SortMultipleOptions> for SortOptions {
239    fn from(value: &SortMultipleOptions) -> Self {
240        SortOptions {
241            descending: value.descending.first().copied().unwrap_or(false),
242            nulls_last: value.nulls_last.first().copied().unwrap_or(false),
243            multithreaded: value.multithreaded,
244            maintain_order: value.maintain_order,
245            limit: value.limit,
246        }
247    }
248}