polars_ops/frame/
is_sorted.rs1use polars_core::chunked_array::ops::SortOptions;
2use polars_core::chunked_array::ops::row_encode::_get_rows_encoded_ca;
3use polars_core::frame::DataFrame;
4use polars_core::prelude::*;
5use polars_error::{PolarsResult, polars_ensure};
6use polars_utils::itertools::Itertools;
7use polars_utils::pl_str::PlSmallStr;
8
9use crate::prelude::*;
10
11pub trait DataFrameIsSorted {
12 fn is_sorted(
13 &self,
14 by: &[PlSmallStr],
15 descending: &[bool],
16 nulls_last: &[bool],
17 ) -> PolarsResult<bool>;
18}
19
20impl DataFrameIsSorted for DataFrame {
21 fn is_sorted(
22 &self,
23 by: &[PlSmallStr],
24 descending: &[bool],
25 nulls_last: &[bool],
26 ) -> PolarsResult<bool> {
27 polars_ensure!(!by.is_empty(), InvalidOperation: "by must specify at least one column");
28 polars_ensure!(descending.len() == by.len(), InvalidOperation: "descending must be of same length as by");
29 polars_ensure!(nulls_last.len() == by.len(), InvalidOperation: "nulls_last must be of same length as by");
30
31 if let [by] = by {
32 let col = self.column(by)?;
33 return SeriesMethods::is_sorted(
34 col.as_materialized_series(),
35 SortOptions::new()
36 .with_order_descending(descending[0])
37 .with_nulls_last(nulls_last[0]),
38 );
39 }
40
41 let by_vec = by
42 .iter()
43 .map(|name| self.column(name).cloned())
44 .try_collect_vec()?;
45 let row_encoded =
46 _get_rows_encoded_ca(PlSmallStr::EMPTY, &by_vec, descending, nulls_last, false)?;
47 let s = Series::new(PlSmallStr::EMPTY, row_encoded);
48 SeriesMethods::is_sorted(&s, SortOptions::new())
49 }
50}