polars-df 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/Cargo.lock +337 -381
  4. data/README.md +4 -3
  5. data/ext/polars/Cargo.toml +5 -4
  6. data/ext/polars/src/apply/mod.rs +7 -3
  7. data/ext/polars/src/conversion.rs +171 -63
  8. data/ext/polars/src/dataframe.rs +19 -23
  9. data/ext/polars/src/error.rs +8 -0
  10. data/ext/polars/src/expr/array.rs +15 -0
  11. data/ext/polars/src/expr/general.rs +39 -9
  12. data/ext/polars/src/expr/list.rs +27 -22
  13. data/ext/polars/src/expr/string.rs +10 -9
  14. data/ext/polars/src/expr.rs +1 -0
  15. data/ext/polars/src/functions/lazy.rs +61 -21
  16. data/ext/polars/src/lazyframe.rs +14 -2
  17. data/ext/polars/src/lib.rs +25 -20
  18. data/ext/polars/src/object.rs +1 -1
  19. data/ext/polars/src/rb_modules.rs +4 -0
  20. data/ext/polars/src/series/construction.rs +28 -2
  21. data/ext/polars/src/series.rs +57 -17
  22. data/lib/polars/array_expr.rb +84 -0
  23. data/lib/polars/array_name_space.rb +77 -0
  24. data/lib/polars/batched_csv_reader.rb +1 -1
  25. data/lib/polars/data_frame.rb +91 -49
  26. data/lib/polars/data_types.rb +163 -29
  27. data/lib/polars/date_time_name_space.rb +17 -3
  28. data/lib/polars/expr.rb +76 -69
  29. data/lib/polars/functions.rb +0 -1
  30. data/lib/polars/group_by.rb +1 -22
  31. data/lib/polars/lazy_frame.rb +82 -30
  32. data/lib/polars/lazy_functions.rb +67 -31
  33. data/lib/polars/list_expr.rb +28 -28
  34. data/lib/polars/list_name_space.rb +13 -13
  35. data/lib/polars/rolling_group_by.rb +4 -2
  36. data/lib/polars/series.rb +70 -16
  37. data/lib/polars/string_expr.rb +137 -11
  38. data/lib/polars/string_name_space.rb +137 -22
  39. data/lib/polars/utils.rb +107 -57
  40. data/lib/polars/version.rb +1 -1
  41. data/lib/polars.rb +3 -0
  42. metadata +5 -2
@@ -2,6 +2,8 @@ use magnus::{block::Proc, IntoValue, RArray, Value};
2
2
  use polars::lazy::dsl;
3
3
  use polars::prelude::*;
4
4
  use polars::series::ops::NullBehavior;
5
+ use polars_core::series::IsSorted;
6
+ use std::any::Any;
5
7
 
6
8
  use crate::apply::lazy::map_single;
7
9
  use crate::conversion::{parse_fill_null_strategy, Wrap};
@@ -201,6 +203,7 @@ impl RbExpr {
201
203
  descending,
202
204
  nulls_last,
203
205
  multithreaded: true,
206
+ maintain_order: false,
204
207
  })
205
208
  .into()
206
209
  }
@@ -212,6 +215,7 @@ impl RbExpr {
212
215
  descending: reverse,
213
216
  nulls_last,
214
217
  multithreaded: true,
218
+ maintain_order: false,
215
219
  })
216
220
  .into()
217
221
  }
@@ -588,6 +592,7 @@ impl RbExpr {
588
592
  center,
589
593
  by,
590
594
  closed_window: closed.map(|c| c.0),
595
+ ..Default::default()
591
596
  };
592
597
  self.inner.clone().rolling_sum(options).into()
593
598
  }
@@ -608,6 +613,7 @@ impl RbExpr {
608
613
  center,
609
614
  by,
610
615
  closed_window: closed.map(|c| c.0),
616
+ ..Default::default()
611
617
  };
612
618
  self.inner.clone().rolling_min(options).into()
613
619
  }
@@ -628,6 +634,7 @@ impl RbExpr {
628
634
  center,
629
635
  by,
630
636
  closed_window: closed.map(|c| c.0),
637
+ ..Default::default()
631
638
  };
632
639
  self.inner.clone().rolling_max(options).into()
633
640
  }
@@ -648,11 +655,13 @@ impl RbExpr {
648
655
  center,
649
656
  by,
650
657
  closed_window: closed.map(|c| c.0),
658
+ ..Default::default()
651
659
  };
652
660
 
653
661
  self.inner.clone().rolling_mean(options).into()
654
662
  }
655
663
 
664
+ #[allow(clippy::too_many_arguments)]
656
665
  pub fn rolling_std(
657
666
  &self,
658
667
  window_size: String,
@@ -661,6 +670,7 @@ impl RbExpr {
661
670
  center: bool,
662
671
  by: Option<String>,
663
672
  closed: Option<Wrap<ClosedWindow>>,
673
+ ddof: u8,
664
674
  ) -> Self {
665
675
  let options = RollingOptions {
666
676
  window_size: Duration::parse(&window_size),
@@ -669,11 +679,13 @@ impl RbExpr {
669
679
  center,
670
680
  by,
671
681
  closed_window: closed.map(|c| c.0),
682
+ fn_params: Some(Arc::new(RollingVarParams { ddof }) as Arc<dyn Any + Send + Sync>),
672
683
  };
673
684
 
674
685
  self.inner.clone().rolling_std(options).into()
675
686
  }
676
687
 
688
+ #[allow(clippy::too_many_arguments)]
677
689
  pub fn rolling_var(
678
690
  &self,
679
691
  window_size: String,
@@ -682,6 +694,7 @@ impl RbExpr {
682
694
  center: bool,
683
695
  by: Option<String>,
684
696
  closed: Option<Wrap<ClosedWindow>>,
697
+ ddof: u8,
685
698
  ) -> Self {
686
699
  let options = RollingOptions {
687
700
  window_size: Duration::parse(&window_size),
@@ -690,6 +703,7 @@ impl RbExpr {
690
703
  center,
691
704
  by,
692
705
  closed_window: closed.map(|c| c.0),
706
+ fn_params: Some(Arc::new(RollingVarParams { ddof }) as Arc<dyn Any + Send + Sync>),
693
707
  };
694
708
 
695
709
  self.inner.clone().rolling_var(options).into()
@@ -711,8 +725,12 @@ impl RbExpr {
711
725
  center,
712
726
  by,
713
727
  closed_window: closed.map(|c| c.0),
728
+ fn_params: Some(Arc::new(RollingQuantileParams {
729
+ prob: 0.5,
730
+ interpol: QuantileInterpolOptions::Linear,
731
+ }) as Arc<dyn Any + Send + Sync>),
714
732
  };
715
- self.inner.clone().rolling_median(options).into()
733
+ self.inner.clone().rolling_quantile(options).into()
716
734
  }
717
735
 
718
736
  #[allow(clippy::too_many_arguments)]
@@ -734,12 +752,13 @@ impl RbExpr {
734
752
  center,
735
753
  by,
736
754
  closed_window: closed.map(|c| c.0),
755
+ fn_params: Some(Arc::new(RollingQuantileParams {
756
+ prob: quantile,
757
+ interpol: interpolation.0,
758
+ }) as Arc<dyn Any + Send + Sync>),
737
759
  };
738
760
 
739
- self.inner
740
- .clone()
741
- .rolling_quantile(quantile, interpolation.0, options)
742
- .into()
761
+ self.inner.clone().rolling_quantile(options).into()
743
762
  }
744
763
 
745
764
  pub fn rolling_skew(&self, window_size: usize, bias: bool) -> Self {
@@ -809,8 +828,8 @@ impl RbExpr {
809
828
  .into()
810
829
  }
811
830
 
812
- pub fn shuffle(&self, seed: Option<u64>) -> Self {
813
- self.inner.clone().shuffle(seed).into()
831
+ pub fn shuffle(&self, seed: Option<u64>, fixed_seed: bool) -> Self {
832
+ self.inner.clone().shuffle(seed, fixed_seed).into()
814
833
  }
815
834
 
816
835
  pub fn sample_n(
@@ -819,10 +838,11 @@ impl RbExpr {
819
838
  with_replacement: bool,
820
839
  shuffle: bool,
821
840
  seed: Option<u64>,
841
+ fixed_seed: bool,
822
842
  ) -> Self {
823
843
  self.inner
824
844
  .clone()
825
- .sample_n(n, with_replacement, shuffle, seed)
845
+ .sample_n(n, with_replacement, shuffle, seed, fixed_seed)
826
846
  .into()
827
847
  }
828
848
 
@@ -832,10 +852,11 @@ impl RbExpr {
832
852
  with_replacement: bool,
833
853
  shuffle: bool,
834
854
  seed: Option<u64>,
855
+ fixed_seed: bool,
835
856
  ) -> Self {
836
857
  self.inner
837
858
  .clone()
838
- .sample_frac(frac, with_replacement, shuffle, seed)
859
+ .sample_frac(frac, with_replacement, shuffle, seed, fixed_seed)
839
860
  .into()
840
861
  }
841
862
 
@@ -930,4 +951,13 @@ impl RbExpr {
930
951
  pub fn hash(&self, seed: u64, seed_1: u64, seed_2: u64, seed_3: u64) -> Self {
931
952
  self.inner.clone().hash(seed, seed_1, seed_2, seed_3).into()
932
953
  }
954
+
955
+ pub fn set_sorted_flag(&self, descending: bool) -> Self {
956
+ let is_sorted = if descending {
957
+ IsSorted::Descending
958
+ } else {
959
+ IsSorted::Ascending
960
+ };
961
+ self.inner.clone().set_sorted_flag(is_sorted).into()
962
+ }
933
963
  }
@@ -8,17 +8,17 @@ use crate::{RbExpr, RbResult};
8
8
 
9
9
  impl RbExpr {
10
10
  pub fn list_arg_max(&self) -> Self {
11
- self.inner.clone().arr().arg_max().into()
11
+ self.inner.clone().list().arg_max().into()
12
12
  }
13
13
 
14
14
  pub fn list_arg_min(&self) -> Self {
15
- self.inner.clone().arr().arg_min().into()
15
+ self.inner.clone().list().arg_min().into()
16
16
  }
17
17
 
18
18
  pub fn list_contains(&self, other: &RbExpr) -> Self {
19
19
  self.inner
20
20
  .clone()
21
- .arr()
21
+ .list()
22
22
  .contains(other.inner.clone())
23
23
  .into()
24
24
  }
@@ -26,53 +26,58 @@ impl RbExpr {
26
26
  pub fn list_count_match(&self, expr: &RbExpr) -> Self {
27
27
  self.inner
28
28
  .clone()
29
- .arr()
29
+ .list()
30
30
  .count_match(expr.inner.clone())
31
31
  .into()
32
32
  }
33
33
 
34
34
  pub fn list_diff(&self, n: i64, null_behavior: Wrap<NullBehavior>) -> RbResult<Self> {
35
- Ok(self.inner.clone().arr().diff(n, null_behavior.0).into())
35
+ Ok(self.inner.clone().list().diff(n, null_behavior.0).into())
36
36
  }
37
37
 
38
38
  pub fn list_eval(&self, expr: &RbExpr, parallel: bool) -> Self {
39
39
  self.inner
40
40
  .clone()
41
- .arr()
41
+ .list()
42
42
  .eval(expr.inner.clone(), parallel)
43
43
  .into()
44
44
  }
45
45
 
46
46
  pub fn list_get(&self, index: &RbExpr) -> Self {
47
- self.inner.clone().arr().get(index.inner.clone()).into()
47
+ self.inner.clone().list().get(index.inner.clone()).into()
48
48
  }
49
49
 
50
50
  pub fn list_join(&self, separator: String) -> Self {
51
- self.inner.clone().arr().join(&separator).into()
51
+ self.inner.clone().list().join(&separator).into()
52
52
  }
53
53
 
54
54
  pub fn list_lengths(&self) -> Self {
55
- self.inner.clone().arr().lengths().into()
55
+ self.inner.clone().list().lengths().into()
56
56
  }
57
57
 
58
58
  pub fn list_max(&self) -> Self {
59
- self.inner.clone().arr().max().into()
59
+ self.inner.clone().list().max().into()
60
60
  }
61
61
 
62
62
  pub fn list_mean(&self) -> Self {
63
- self.inner.clone().arr().mean().with_fmt("arr.mean").into()
63
+ self.inner
64
+ .clone()
65
+ .list()
66
+ .mean()
67
+ .with_fmt("list.mean")
68
+ .into()
64
69
  }
65
70
 
66
71
  pub fn list_min(&self) -> Self {
67
- self.inner.clone().arr().min().into()
72
+ self.inner.clone().list().min().into()
68
73
  }
69
74
 
70
75
  pub fn list_reverse(&self) -> Self {
71
- self.inner.clone().arr().reverse().into()
76
+ self.inner.clone().list().reverse().into()
72
77
  }
73
78
 
74
79
  pub fn list_shift(&self, periods: i64) -> Self {
75
- self.inner.clone().arr().shift(periods).into()
80
+ self.inner.clone().list().shift(periods).into()
76
81
  }
77
82
 
78
83
  pub fn list_slice(&self, offset: &RbExpr, length: Option<&RbExpr>) -> Self {
@@ -82,7 +87,7 @@ impl RbExpr {
82
87
  };
83
88
  self.inner
84
89
  .clone()
85
- .arr()
90
+ .list()
86
91
  .slice(offset.inner.clone(), length)
87
92
  .into()
88
93
  }
@@ -90,23 +95,23 @@ impl RbExpr {
90
95
  pub fn list_sort(&self, reverse: bool) -> Self {
91
96
  self.inner
92
97
  .clone()
93
- .arr()
98
+ .list()
94
99
  .sort(SortOptions {
95
100
  descending: reverse,
96
101
  ..Default::default()
97
102
  })
98
- .with_fmt("arr.sort")
103
+ .with_fmt("list.sort")
99
104
  .into()
100
105
  }
101
106
 
102
107
  pub fn list_sum(&self) -> Self {
103
- self.inner.clone().arr().sum().with_fmt("arr.sum").into()
108
+ self.inner.clone().list().sum().with_fmt("list.sum").into()
104
109
  }
105
110
 
106
111
  pub fn list_take(&self, index: &RbExpr, null_on_oob: bool) -> Self {
107
112
  self.inner
108
113
  .clone()
109
- .arr()
114
+ .list()
110
115
  .take(index.inner.clone(), null_on_oob)
111
116
  .into()
112
117
  }
@@ -129,7 +134,7 @@ impl RbExpr {
129
134
  Ok(self
130
135
  .inner
131
136
  .clone()
132
- .arr()
137
+ .list()
133
138
  .to_struct(width_strat.0, name_gen, upper_bound)
134
139
  .into())
135
140
  }
@@ -138,9 +143,9 @@ impl RbExpr {
138
143
  let e = self.inner.clone();
139
144
 
140
145
  if maintain_order {
141
- e.arr().unique_stable().into()
146
+ e.list().unique_stable().into()
142
147
  } else {
143
- e.arr().unique().into()
148
+ e.list().unique().into()
144
149
  }
145
150
  }
146
151
  }
@@ -20,12 +20,10 @@ impl RbExpr {
20
20
  strict,
21
21
  exact,
22
22
  cache,
23
- ..Default::default()
24
23
  };
25
24
  self.inner.clone().str().to_date(options).into()
26
25
  }
27
26
 
28
- #[allow(clippy::too_many_arguments)]
29
27
  pub fn str_to_datetime(
30
28
  &self,
31
29
  format: Option<String>,
@@ -34,16 +32,12 @@ impl RbExpr {
34
32
  strict: bool,
35
33
  exact: bool,
36
34
  cache: bool,
37
- utc: bool,
38
- tz_aware: bool,
39
35
  ) -> Self {
40
36
  let options = StrptimeOptions {
41
37
  format,
42
38
  strict,
43
39
  exact,
44
40
  cache,
45
- tz_aware,
46
- utc,
47
41
  };
48
42
  self.inner
49
43
  .clone()
@@ -58,7 +52,6 @@ impl RbExpr {
58
52
  strict,
59
53
  cache,
60
54
  exact: true,
61
- ..Default::default()
62
55
  };
63
56
  self.inner.clone().str().to_time(options).into()
64
57
  }
@@ -87,6 +80,10 @@ impl RbExpr {
87
80
  .into()
88
81
  }
89
82
 
83
+ pub fn str_explode(&self) -> Self {
84
+ self.inner.clone().str().explode().into()
85
+ }
86
+
90
87
  pub fn str_to_uppercase(&self) -> Self {
91
88
  self.inner.clone().str().to_uppercase().into()
92
89
  }
@@ -233,7 +230,11 @@ impl RbExpr {
233
230
  .into()
234
231
  }
235
232
 
236
- pub fn str_json_extract(&self, dtype: Option<Wrap<DataType>>) -> Self {
233
+ pub fn str_json_extract(
234
+ &self,
235
+ dtype: Option<Wrap<DataType>>,
236
+ infer_schema_len: Option<usize>,
237
+ ) -> Self {
237
238
  let dtype = dtype.map(|wrap| wrap.0);
238
239
 
239
240
  let output_type = match dtype.clone() {
@@ -243,7 +244,7 @@ impl RbExpr {
243
244
 
244
245
  let function = move |s: Series| {
245
246
  let ca = s.utf8()?;
246
- match ca.json_extract(dtype.clone()) {
247
+ match ca.json_extract(dtype.clone(), infer_schema_len) {
247
248
  Ok(ca) => Ok(Some(ca.into_series())),
248
249
  Err(e) => Err(PolarsError::ComputeError(format!("{e:?}").into())),
249
250
  }
@@ -1,3 +1,4 @@
1
+ mod array;
1
2
  mod binary;
2
3
  mod categorical;
3
4
  mod datetime;
@@ -1,4 +1,5 @@
1
- use magnus::{class, RArray, RString, Value};
1
+ use magnus::encoding::{self, EncodingCapable};
2
+ use magnus::{class, Float, Integer, RArray, RString, Value};
2
3
  use polars::lazy::dsl;
3
4
  use polars::prelude::*;
4
5
 
@@ -6,7 +7,7 @@ use crate::apply::lazy::binary_lambda;
6
7
  use crate::conversion::{get_lf, get_rbseq, Wrap};
7
8
  use crate::prelude::vec_extract_wrapped;
8
9
  use crate::rb_exprs_to_exprs;
9
- use crate::{RbDataFrame, RbExpr, RbLazyFrame, RbPolarsErr, RbResult, RbSeries};
10
+ use crate::{RbDataFrame, RbExpr, RbLazyFrame, RbPolarsErr, RbResult, RbSeries, RbValueError};
10
11
 
11
12
  macro_rules! set_unwrapped_or_0 {
12
13
  ($($var:ident),+ $(,)?) => {
@@ -57,7 +58,12 @@ pub fn cols(names: Vec<String>) -> RbExpr {
57
58
  dsl::cols(names).into()
58
59
  }
59
60
 
60
- pub fn concat_lf(lfs: Value, rechunk: bool, parallel: bool) -> RbResult<RbLazyFrame> {
61
+ pub fn concat_lf(
62
+ lfs: Value,
63
+ rechunk: bool,
64
+ parallel: bool,
65
+ to_supertypes: bool,
66
+ ) -> RbResult<RbLazyFrame> {
61
67
  let (seq, len) = get_rbseq(lfs)?;
62
68
  let mut lfs = Vec::with_capacity(len);
63
69
 
@@ -67,7 +73,15 @@ pub fn concat_lf(lfs: Value, rechunk: bool, parallel: bool) -> RbResult<RbLazyFr
67
73
  lfs.push(lf);
68
74
  }
69
75
 
70
- let lf = polars::lazy::dsl::concat(lfs, rechunk, parallel).map_err(RbPolarsErr::from)?;
76
+ let lf = dsl::concat(
77
+ lfs,
78
+ UnionArgs {
79
+ rechunk,
80
+ parallel,
81
+ to_supertypes,
82
+ },
83
+ )
84
+ .map_err(RbPolarsErr::from)?;
71
85
  Ok(lf.into())
72
86
  }
73
87
 
@@ -135,16 +149,11 @@ pub fn cumfold(acc: &RbExpr, lambda: Value, exprs: RArray, include_init: bool) -
135
149
  Ok(polars::lazy::dsl::cumfold_exprs(acc.inner.clone(), func, exprs, include_init).into())
136
150
  }
137
151
 
138
- // TODO improve
139
- pub fn lit(value: Value) -> RbResult<RbExpr> {
140
- if value.is_nil() {
141
- Ok(dsl::lit(Null {}).into())
142
- } else if let Ok(series) = value.try_convert::<&RbSeries>() {
143
- Ok(dsl::lit(series.series.borrow().clone()).into())
144
- } else if let Some(v) = RString::from_value(value) {
145
- Ok(dsl::lit(v.try_convert::<String>()?).into())
146
- } else if value.is_kind_of(class::integer()) {
147
- match value.try_convert::<i64>() {
152
+ pub fn lit(value: Value, allow_object: bool) -> RbResult<RbExpr> {
153
+ if value.is_kind_of(class::true_class()) || value.is_kind_of(class::false_class()) {
154
+ Ok(dsl::lit(value.try_convert::<bool>()?).into())
155
+ } else if let Some(v) = Integer::from_value(value) {
156
+ match v.try_convert::<i64>() {
148
157
  Ok(val) => {
149
158
  if val > 0 && val < i32::MAX as i64 || val < 0 && val > i32::MIN as i64 {
150
159
  Ok(dsl::lit(val as i32).into())
@@ -157,17 +166,47 @@ pub fn lit(value: Value) -> RbResult<RbExpr> {
157
166
  Ok(dsl::lit(val).into())
158
167
  }
159
168
  }
169
+ } else if let Some(v) = Float::from_value(value) {
170
+ Ok(dsl::lit(v.try_convert::<f64>()?).into())
171
+ } else if let Some(v) = RString::from_value(value) {
172
+ if v.enc_get() == encoding::Index::utf8() {
173
+ Ok(dsl::lit(v.try_convert::<String>()?).into())
174
+ } else {
175
+ Ok(dsl::lit(unsafe { v.as_slice() }).into())
176
+ }
177
+ } else if let Ok(series) = value.try_convert::<&RbSeries>() {
178
+ Ok(dsl::lit(series.series.borrow().clone()).into())
179
+ } else if value.is_nil() {
180
+ Ok(dsl::lit(Null {}).into())
181
+ } else if allow_object {
182
+ todo!()
160
183
  } else {
161
- Ok(dsl::lit(value.try_convert::<f64>()?).into())
184
+ Err(RbValueError::new_err(format!(
185
+ "could not convert value {:?} as a Literal",
186
+ value.to_string()
187
+ )))
162
188
  }
163
189
  }
164
190
 
165
- pub fn repeat(value: Value, n_times: &RbExpr) -> RbResult<RbExpr> {
166
- if value.is_nil() {
167
- Ok(polars::lazy::dsl::repeat(Null {}, n_times.inner.clone()).into())
168
- } else {
169
- todo!();
191
+ pub fn repeat(value: &RbExpr, n: &RbExpr, dtype: Option<Wrap<DataType>>) -> RbResult<RbExpr> {
192
+ let mut value = value.inner.clone();
193
+ let n = n.inner.clone();
194
+
195
+ if let Some(dtype) = dtype {
196
+ value = value.cast(dtype.0);
197
+ }
198
+
199
+ if let Expr::Literal(lv) = &value {
200
+ let av = lv.to_anyvalue().unwrap();
201
+ // Integer inputs that fit in Int32 are parsed as such
202
+ if let DataType::Int64 = av.dtype() {
203
+ let int_value = av.try_extract::<i64>().unwrap();
204
+ if int_value >= i32::MIN as i64 && int_value <= i32::MAX as i64 {
205
+ value = value.cast(DataType::Int32);
206
+ }
207
+ }
170
208
  }
209
+ Ok(dsl::repeat(value, n).into())
171
210
  }
172
211
 
173
212
  pub fn pearson_corr(a: &RbExpr, b: &RbExpr, ddof: u8) -> RbExpr {
@@ -203,7 +242,8 @@ pub fn dtype_cols2(dtypes: RArray) -> RbResult<RbExpr> {
203
242
  Ok(crate::functions::lazy::dtype_cols(dtypes))
204
243
  }
205
244
 
245
+ // TODO rename to sum_horizontal
206
246
  pub fn sum_exprs(exprs: RArray) -> RbResult<RbExpr> {
207
247
  let exprs = rb_exprs_to_exprs(exprs)?;
208
- Ok(polars::lazy::dsl::sum_exprs(exprs).into())
248
+ Ok(polars::lazy::dsl::sum_horizontal(exprs).into())
209
249
  }
@@ -230,7 +230,13 @@ impl RbLazyFrame {
230
230
  ldf.into()
231
231
  }
232
232
 
233
- pub fn sort(&self, by_column: String, reverse: bool, nulls_last: bool) -> Self {
233
+ pub fn sort(
234
+ &self,
235
+ by_column: String,
236
+ reverse: bool,
237
+ nulls_last: bool,
238
+ maintain_order: bool,
239
+ ) -> Self {
234
240
  let ldf = self.ldf.clone();
235
241
  ldf.sort(
236
242
  &by_column,
@@ -238,6 +244,7 @@ impl RbLazyFrame {
238
244
  descending: reverse,
239
245
  nulls_last,
240
246
  multithreaded: true,
247
+ maintain_order,
241
248
  },
242
249
  )
243
250
  .into()
@@ -248,10 +255,13 @@ impl RbLazyFrame {
248
255
  by_column: RArray,
249
256
  reverse: Vec<bool>,
250
257
  nulls_last: bool,
258
+ maintain_order: bool,
251
259
  ) -> RbResult<Self> {
252
260
  let ldf = self.ldf.clone();
253
261
  let exprs = rb_exprs_to_exprs(by_column)?;
254
- Ok(ldf.sort_by_exprs(exprs, reverse, nulls_last).into())
262
+ Ok(ldf
263
+ .sort_by_exprs(exprs, reverse, nulls_last, maintain_order)
264
+ .into())
255
265
  }
256
266
 
257
267
  pub fn cache(&self) -> Self {
@@ -328,6 +338,7 @@ impl RbLazyFrame {
328
338
  offset: String,
329
339
  closed: Wrap<ClosedWindow>,
330
340
  by: RArray,
341
+ check_sorted: bool,
331
342
  ) -> RbResult<RbLazyGroupBy> {
332
343
  let closed_window = closed.0;
333
344
  let ldf = self.ldf.clone();
@@ -340,6 +351,7 @@ impl RbLazyFrame {
340
351
  period: Duration::parse(&period),
341
352
  offset: Duration::parse(&offset),
342
353
  closed_window,
354
+ check_sorted,
343
355
  },
344
356
  );
345
357