polars-df 0.2.5 → 0.3.1

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/Cargo.lock +290 -137
  4. data/Cargo.toml +1 -1
  5. data/README.md +40 -2
  6. data/ext/polars/Cargo.toml +5 -4
  7. data/ext/polars/src/apply/dataframe.rs +6 -6
  8. data/ext/polars/src/apply/series.rs +10 -10
  9. data/ext/polars/src/batched_csv.rs +6 -4
  10. data/ext/polars/src/conversion.rs +56 -17
  11. data/ext/polars/src/dataframe.rs +65 -43
  12. data/ext/polars/src/error.rs +16 -8
  13. data/ext/polars/src/file.rs +5 -4
  14. data/ext/polars/src/lazy/apply.rs +1 -1
  15. data/ext/polars/src/lazy/dataframe.rs +12 -6
  16. data/ext/polars/src/lazy/dsl.rs +99 -45
  17. data/ext/polars/src/lazy/meta.rs +10 -9
  18. data/ext/polars/src/lib.rs +33 -29
  19. data/ext/polars/src/numo.rs +57 -0
  20. data/ext/polars/src/object.rs +2 -1
  21. data/ext/polars/src/series.rs +67 -53
  22. data/lib/polars/cat_expr.rb +0 -4
  23. data/lib/polars/cat_name_space.rb +0 -4
  24. data/lib/polars/convert.rb +0 -7
  25. data/lib/polars/data_frame.rb +165 -209
  26. data/lib/polars/data_types.rb +4 -0
  27. data/lib/polars/date_time_expr.rb +19 -151
  28. data/lib/polars/date_time_name_space.rb +17 -17
  29. data/lib/polars/expr.rb +68 -315
  30. data/lib/polars/group_by.rb +79 -51
  31. data/lib/polars/io.rb +1 -1
  32. data/lib/polars/lazy_frame.rb +1 -103
  33. data/lib/polars/lazy_functions.rb +0 -26
  34. data/lib/polars/lazy_group_by.rb +0 -8
  35. data/lib/polars/list_expr.rb +5 -27
  36. data/lib/polars/list_name_space.rb +5 -8
  37. data/lib/polars/plot.rb +109 -0
  38. data/lib/polars/series.rb +61 -19
  39. data/lib/polars/string_expr.rb +20 -76
  40. data/lib/polars/string_name_space.rb +5 -15
  41. data/lib/polars/struct_expr.rb +0 -2
  42. data/lib/polars/version.rb +1 -1
  43. data/lib/polars.rb +1 -0
  44. metadata +5 -3
@@ -1,4 +1,4 @@
1
- use magnus::exception::arg_error;
1
+ use magnus::exception;
2
2
  use magnus::Error;
3
3
  use polars::error::ArrowError;
4
4
  use polars::prelude::PolarsError;
@@ -8,23 +8,23 @@ pub struct RbPolarsErr {}
8
8
  impl RbPolarsErr {
9
9
  // convert to Error instead of Self
10
10
  pub fn from(e: PolarsError) -> Error {
11
- Error::runtime_error(e.to_string())
11
+ Error::new(exception::runtime_error(), e.to_string())
12
12
  }
13
13
 
14
14
  pub fn arrow(e: ArrowError) -> Error {
15
- Error::runtime_error(e.to_string())
15
+ Error::new(exception::runtime_error(), e.to_string())
16
16
  }
17
17
 
18
18
  pub fn io(e: std::io::Error) -> Error {
19
- Error::runtime_error(e.to_string())
19
+ Error::new(exception::runtime_error(), e.to_string())
20
20
  }
21
21
 
22
22
  pub fn other(message: String) -> Error {
23
- Error::runtime_error(message)
23
+ Error::new(exception::runtime_error(), message)
24
24
  }
25
25
 
26
26
  pub fn todo() -> Error {
27
- Error::runtime_error("not implemented yet")
27
+ Error::new(exception::runtime_error(), "not implemented yet")
28
28
  }
29
29
  }
30
30
 
@@ -32,7 +32,7 @@ pub struct RbValueError {}
32
32
 
33
33
  impl RbValueError {
34
34
  pub fn new_err(message: String) -> Error {
35
- Error::new(arg_error(), message)
35
+ Error::new(exception::arg_error(), message)
36
36
  }
37
37
  }
38
38
 
@@ -40,6 +40,14 @@ pub struct ComputeError {}
40
40
 
41
41
  impl ComputeError {
42
42
  pub fn new_err(message: String) -> Error {
43
- Error::runtime_error(message)
43
+ Error::new(exception::runtime_error(), message)
44
44
  }
45
45
  }
46
+
47
+ #[macro_export]
48
+ macro_rules! raise_err(
49
+ ($msg:expr, $err:ident) => {{
50
+ Err(PolarsError::$err($msg.into())).map_err(RbPolarsErr::from)?;
51
+ unreachable!()
52
+ }}
53
+ );
@@ -1,4 +1,4 @@
1
- use magnus::{Error, RString, Value};
1
+ use magnus::{exception, Error, RString, Value};
2
2
  use polars::io::mmap::MmapBytesReader;
3
3
  use std::fs::File;
4
4
  use std::io::Cursor;
@@ -9,9 +9,10 @@ use crate::RbResult;
9
9
  pub fn get_file_like(f: Value, truncate: bool) -> RbResult<File> {
10
10
  let str_slice = f.try_convert::<PathBuf>()?;
11
11
  let f = if truncate {
12
- File::create(str_slice).map_err(|e| Error::runtime_error(e.to_string()))?
12
+ File::create(str_slice)
13
+ .map_err(|e| Error::new(exception::runtime_error(), e.to_string()))?
13
14
  } else {
14
- File::open(str_slice).map_err(|e| Error::runtime_error(e.to_string()))?
15
+ File::open(str_slice).map_err(|e| Error::new(exception::runtime_error(), e.to_string()))?
15
16
  };
16
17
  Ok(f)
17
18
  }
@@ -23,7 +24,7 @@ pub fn get_mmap_bytes_reader(rb_f: Value) -> RbResult<Box<dyn MmapBytesReader>>
23
24
  Ok(Box::new(Cursor::new(bytes.to_vec())))
24
25
  } else {
25
26
  let p = rb_f.try_convert::<PathBuf>()?;
26
- let f = File::open(p).map_err(|e| Error::runtime_error(e.to_string()))?;
27
+ let f = File::open(p).map_err(|e| Error::new(exception::runtime_error(), e.to_string()))?;
27
28
  Ok(Box::new(f))
28
29
  }
29
30
  }
@@ -4,7 +4,7 @@ use polars::prelude::*;
4
4
  use crate::lazy::dsl::RbExpr;
5
5
  use crate::Wrap;
6
6
 
7
- pub fn binary_lambda(_lambda: Value, _a: Series, _b: Series) -> PolarsResult<Series> {
7
+ pub fn binary_lambda(_lambda: Value, _a: Series, _b: Series) -> PolarsResult<Option<Series>> {
8
8
  todo!();
9
9
  }
10
10
 
@@ -1,4 +1,4 @@
1
- use magnus::{RArray, RHash, Value};
1
+ use magnus::{IntoValue, RArray, RHash, Value};
2
2
  use polars::io::RowCount;
3
3
  use polars::lazy::frame::{LazyFrame, LazyGroupBy};
4
4
  use polars::prelude::*;
@@ -140,7 +140,7 @@ impl RbLazyFrame {
140
140
  .with_infer_schema_length(infer_schema_length)
141
141
  .with_delimiter(delimiter)
142
142
  .has_header(has_header)
143
- .with_ignore_parser_errors(ignore_errors)
143
+ .with_ignore_errors(ignore_errors)
144
144
  .with_skip_rows(skip_rows)
145
145
  .with_n_rows(n_rows)
146
146
  .with_cache(cache)
@@ -180,6 +180,8 @@ impl RbLazyFrame {
180
180
  rechunk,
181
181
  row_count,
182
182
  low_memory,
183
+ // TODO support cloud options
184
+ cloud_options: None,
183
185
  };
184
186
  let lf = LazyFrame::scan_parquet(path, args).map_err(RbPolarsErr::from)?;
185
187
  Ok(lf.into())
@@ -254,6 +256,7 @@ impl RbLazyFrame {
254
256
  SortOptions {
255
257
  descending: reverse,
256
258
  nulls_last,
259
+ multithreaded: true,
257
260
  },
258
261
  )
259
262
  .into()
@@ -597,10 +600,10 @@ impl RbLazyFrame {
597
600
  Ok(self.get_schema()?.iter_names().cloned().collect())
598
601
  }
599
602
 
600
- pub fn dtypes(&self) -> RbResult<Vec<Value>> {
603
+ pub fn dtypes(&self) -> RbResult<RArray> {
601
604
  let schema = self.get_schema()?;
602
- let iter = schema.iter_dtypes().map(|dt| Wrap(dt.clone()).into());
603
- Ok(iter.collect())
605
+ let iter = schema.iter_dtypes().map(|dt| Wrap(dt.clone()).into_value());
606
+ Ok(RArray::from_iter(iter))
604
607
  }
605
608
 
606
609
  pub fn schema(&self) -> RbResult<RHash> {
@@ -610,7 +613,10 @@ impl RbLazyFrame {
610
613
  schema.iter_fields().for_each(|fld| {
611
614
  // TODO remove unwrap
612
615
  schema_dict
613
- .aset::<String, Value>(fld.name().clone(), Wrap(fld.data_type().clone()).into())
616
+ .aset::<String, Value>(
617
+ fld.name().clone(),
618
+ Wrap(fld.data_type().clone()).into_value(),
619
+ )
614
620
  .unwrap();
615
621
  });
616
622
  Ok(schema_dict)
@@ -1,5 +1,5 @@
1
1
  use magnus::block::Proc;
2
- use magnus::{class, RArray, RString, Value};
2
+ use magnus::{class, IntoValue, RArray, RString, Value};
3
3
  use polars::chunked_array::ops::SortOptions;
4
4
  use polars::lazy::dsl;
5
5
  use polars::lazy::dsl::Operator;
@@ -214,6 +214,7 @@ impl RbExpr {
214
214
  .sort_with(SortOptions {
215
215
  descending,
216
216
  nulls_last,
217
+ multithreaded: true,
217
218
  })
218
219
  .into()
219
220
  }
@@ -224,6 +225,7 @@ impl RbExpr {
224
225
  .arg_sort(SortOptions {
225
226
  descending: reverse,
226
227
  nulls_last,
228
+ multithreaded: true,
227
229
  })
228
230
  .into()
229
231
  }
@@ -240,10 +242,10 @@ impl RbExpr {
240
242
  self.clone().inner.arg_min().into()
241
243
  }
242
244
 
243
- pub fn search_sorted(&self, element: &RbExpr) -> Self {
245
+ pub fn search_sorted(&self, element: &RbExpr, side: Wrap<SearchSortedSide>) -> Self {
244
246
  self.inner
245
247
  .clone()
246
- .search_sorted(element.inner.clone())
248
+ .search_sorted(element.inner.clone(), side.0)
247
249
  .into()
248
250
  }
249
251
 
@@ -287,7 +289,10 @@ impl RbExpr {
287
289
  Ok(self
288
290
  .inner
289
291
  .clone()
290
- .apply(move |s| s.fill_null(strat), GetOutput::same_type())
292
+ .apply(
293
+ move |s| s.fill_null(strat).map(Some),
294
+ GetOutput::same_type(),
295
+ )
291
296
  .with_fmt("fill_null_with_strategy")
292
297
  .into())
293
298
  }
@@ -335,7 +340,10 @@ impl RbExpr {
335
340
  pub fn take_every(&self, n: usize) -> Self {
336
341
  self.clone()
337
342
  .inner
338
- .map(move |s: Series| Ok(s.take_every(n)), GetOutput::same_type())
343
+ .map(
344
+ move |s: Series| Ok(Some(s.take_every(n))),
345
+ GetOutput::same_type(),
346
+ )
339
347
  .with_fmt("take_every")
340
348
  .into()
341
349
  }
@@ -365,7 +373,7 @@ impl RbExpr {
365
373
  pub fn rechunk(&self) -> Self {
366
374
  self.inner
367
375
  .clone()
368
- .map(|s| Ok(s.rechunk()), GetOutput::same_type())
376
+ .map(|s| Ok(Some(s.rechunk())), GetOutput::same_type())
369
377
  .into()
370
378
  }
371
379
 
@@ -527,6 +535,7 @@ impl RbExpr {
527
535
  exact,
528
536
  cache,
529
537
  tz_aware: false,
538
+ utc: false,
530
539
  })
531
540
  .into()
532
541
  }
@@ -538,6 +547,7 @@ impl RbExpr {
538
547
  exact: bool,
539
548
  cache: bool,
540
549
  tz_aware: bool,
550
+ utc: bool,
541
551
  ) -> Self {
542
552
  let tu = match fmt {
543
553
  Some(ref fmt) => {
@@ -565,6 +575,7 @@ impl RbExpr {
565
575
  exact,
566
576
  cache,
567
577
  tz_aware,
578
+ utc,
568
579
  })
569
580
  .into()
570
581
  }
@@ -586,26 +597,27 @@ impl RbExpr {
586
597
  exact,
587
598
  cache,
588
599
  tz_aware: false,
600
+ utc: false,
589
601
  })
590
602
  .into()
591
603
  }
592
604
 
593
- pub fn str_strip(&self, matches: Option<char>) -> Self {
605
+ pub fn str_strip(&self, matches: Option<String>) -> Self {
594
606
  self.inner.clone().str().strip(matches).into()
595
607
  }
596
608
 
597
- pub fn str_rstrip(&self, matches: Option<char>) -> Self {
609
+ pub fn str_rstrip(&self, matches: Option<String>) -> Self {
598
610
  self.inner.clone().str().rstrip(matches).into()
599
611
  }
600
612
 
601
- pub fn str_lstrip(&self, matches: Option<char>) -> Self {
613
+ pub fn str_lstrip(&self, matches: Option<String>) -> Self {
602
614
  self.inner.clone().str().lstrip(matches).into()
603
615
  }
604
616
 
605
617
  pub fn str_slice(&self, start: i64, length: Option<u64>) -> Self {
606
618
  let function = move |s: Series| {
607
619
  let ca = s.utf8()?;
608
- Ok(ca.str_slice(start, length)?.into_series())
620
+ Ok(Some(ca.str_slice(start, length)?.into_series()))
609
621
  };
610
622
  self.clone()
611
623
  .inner
@@ -625,7 +637,7 @@ impl RbExpr {
625
637
  pub fn str_lengths(&self) -> Self {
626
638
  let function = |s: Series| {
627
639
  let ca = s.utf8()?;
628
- Ok(ca.str_lengths().into_series())
640
+ Ok(Some(ca.str_lengths().into_series()))
629
641
  };
630
642
  self.clone()
631
643
  .inner
@@ -637,7 +649,7 @@ impl RbExpr {
637
649
  pub fn str_n_chars(&self) -> Self {
638
650
  let function = |s: Series| {
639
651
  let ca = s.utf8()?;
640
- Ok(ca.str_n_chars().into_series())
652
+ Ok(Some(ca.str_n_chars().into_series()))
641
653
  };
642
654
  self.clone()
643
655
  .inner
@@ -674,37 +686,51 @@ impl RbExpr {
674
686
  self.clone().inner.str().rjust(width, fillchar).into()
675
687
  }
676
688
 
677
- pub fn str_contains(&self, pat: String, literal: Option<bool>) -> Self {
689
+ pub fn str_contains(&self, pat: &RbExpr, literal: Option<bool>, strict: bool) -> Self {
678
690
  match literal {
679
- Some(true) => self.inner.clone().str().contains_literal(pat).into(),
680
- _ => self.inner.clone().str().contains(pat).into(),
691
+ Some(true) => self
692
+ .inner
693
+ .clone()
694
+ .str()
695
+ .contains_literal(pat.inner.clone())
696
+ .into(),
697
+ _ => self
698
+ .inner
699
+ .clone()
700
+ .str()
701
+ .contains(pat.inner.clone(), strict)
702
+ .into(),
681
703
  }
682
704
  }
683
705
 
684
- pub fn str_ends_with(&self, sub: String) -> Self {
685
- self.inner.clone().str().ends_with(sub).into()
706
+ pub fn str_ends_with(&self, sub: &RbExpr) -> Self {
707
+ self.inner.clone().str().ends_with(sub.inner.clone()).into()
686
708
  }
687
709
 
688
- pub fn str_starts_with(&self, sub: String) -> Self {
689
- self.inner.clone().str().starts_with(sub).into()
710
+ pub fn str_starts_with(&self, sub: &RbExpr) -> Self {
711
+ self.inner
712
+ .clone()
713
+ .str()
714
+ .starts_with(sub.inner.clone())
715
+ .into()
690
716
  }
691
717
 
692
718
  pub fn str_hex_encode(&self) -> Self {
693
719
  self.clone()
694
720
  .inner
695
721
  .map(
696
- move |s| s.utf8().map(|s| s.hex_encode().into_series()),
722
+ move |s| s.utf8().map(|s| Some(s.hex_encode().into_series())),
697
723
  GetOutput::same_type(),
698
724
  )
699
725
  .with_fmt("str.hex_encode")
700
726
  .into()
701
727
  }
702
728
 
703
- pub fn str_hex_decode(&self, strict: Option<bool>) -> Self {
729
+ pub fn str_hex_decode(&self, strict: bool) -> Self {
704
730
  self.clone()
705
731
  .inner
706
732
  .map(
707
- move |s| s.utf8()?.hex_decode(strict).map(|s| s.into_series()),
733
+ move |s| s.utf8()?.hex_decode(strict).map(|s| Some(s.into_series())),
708
734
  GetOutput::same_type(),
709
735
  )
710
736
  .with_fmt("str.hex_decode")
@@ -715,18 +741,22 @@ impl RbExpr {
715
741
  self.clone()
716
742
  .inner
717
743
  .map(
718
- move |s| s.utf8().map(|s| s.base64_encode().into_series()),
744
+ move |s| s.utf8().map(|s| Some(s.base64_encode().into_series())),
719
745
  GetOutput::same_type(),
720
746
  )
721
747
  .with_fmt("str.base64_encode")
722
748
  .into()
723
749
  }
724
750
 
725
- pub fn str_base64_decode(&self, strict: Option<bool>) -> Self {
751
+ pub fn str_base64_decode(&self, strict: bool) -> Self {
726
752
  self.clone()
727
753
  .inner
728
754
  .map(
729
- move |s| s.utf8()?.base64_decode(strict).map(|s| s.into_series()),
755
+ move |s| {
756
+ s.utf8()?
757
+ .base64_decode(strict)
758
+ .map(|s| Some(s.into_series()))
759
+ },
730
760
  GetOutput::same_type(),
731
761
  )
732
762
  .with_fmt("str.base64_decode")
@@ -737,7 +767,7 @@ impl RbExpr {
737
767
  let function = move |s: Series| {
738
768
  let ca = s.utf8()?;
739
769
  match ca.json_path_match(&pat) {
740
- Ok(ca) => Ok(ca.into_series()),
770
+ Ok(ca) => Ok(Some(ca.into_series())),
741
771
  Err(e) => Err(PolarsError::ComputeError(format!("{:?}", e).into())),
742
772
  }
743
773
  };
@@ -864,7 +894,7 @@ impl RbExpr {
864
894
  self.inner
865
895
  .clone()
866
896
  .map(
867
- |s| Ok(s.duration()?.days().into_series()),
897
+ |s| Ok(Some(s.duration()?.days().into_series())),
868
898
  GetOutput::from_type(DataType::Int64),
869
899
  )
870
900
  .into()
@@ -874,7 +904,7 @@ impl RbExpr {
874
904
  self.inner
875
905
  .clone()
876
906
  .map(
877
- |s| Ok(s.duration()?.hours().into_series()),
907
+ |s| Ok(Some(s.duration()?.hours().into_series())),
878
908
  GetOutput::from_type(DataType::Int64),
879
909
  )
880
910
  .into()
@@ -884,7 +914,7 @@ impl RbExpr {
884
914
  self.inner
885
915
  .clone()
886
916
  .map(
887
- |s| Ok(s.duration()?.minutes().into_series()),
917
+ |s| Ok(Some(s.duration()?.minutes().into_series())),
888
918
  GetOutput::from_type(DataType::Int64),
889
919
  )
890
920
  .into()
@@ -894,7 +924,7 @@ impl RbExpr {
894
924
  self.inner
895
925
  .clone()
896
926
  .map(
897
- |s| Ok(s.duration()?.seconds().into_series()),
927
+ |s| Ok(Some(s.duration()?.seconds().into_series())),
898
928
  GetOutput::from_type(DataType::Int64),
899
929
  )
900
930
  .into()
@@ -904,7 +934,7 @@ impl RbExpr {
904
934
  self.inner
905
935
  .clone()
906
936
  .map(
907
- |s| Ok(s.duration()?.nanoseconds().into_series()),
937
+ |s| Ok(Some(s.duration()?.nanoseconds().into_series())),
908
938
  GetOutput::from_type(DataType::Int64),
909
939
  )
910
940
  .into()
@@ -914,7 +944,7 @@ impl RbExpr {
914
944
  self.inner
915
945
  .clone()
916
946
  .map(
917
- |s| Ok(s.duration()?.microseconds().into_series()),
947
+ |s| Ok(Some(s.duration()?.microseconds().into_series())),
918
948
  GetOutput::from_type(DataType::Int64),
919
949
  )
920
950
  .into()
@@ -924,7 +954,7 @@ impl RbExpr {
924
954
  self.inner
925
955
  .clone()
926
956
  .map(
927
- |s| Ok(s.duration()?.milliseconds().into_series()),
957
+ |s| Ok(Some(s.duration()?.milliseconds().into_series())),
928
958
  GetOutput::from_type(DataType::Int64),
929
959
  )
930
960
  .into()
@@ -945,7 +975,7 @@ impl RbExpr {
945
975
  .map(
946
976
  |s| {
947
977
  s.timestamp(TimeUnit::Milliseconds)
948
- .map(|ca| (ca / 1000).into_series())
978
+ .map(|ca| Some((ca / 1000).into_series()))
949
979
  },
950
980
  GetOutput::from_type(DataType::Int64),
951
981
  )
@@ -956,18 +986,19 @@ impl RbExpr {
956
986
  self.inner.clone().dt().with_time_unit(tu.0).into()
957
987
  }
958
988
 
959
- pub fn dt_with_time_zone(&self, tz: Option<TimeZone>) -> Self {
960
- self.inner.clone().dt().with_time_zone(tz).into()
989
+ pub fn dt_convert_time_zone(&self, tz: TimeZone) -> Self {
990
+ self.inner.clone().dt().convert_time_zone(tz).into()
961
991
  }
962
992
 
963
993
  pub fn dt_cast_time_unit(&self, tu: Wrap<TimeUnit>) -> Self {
964
994
  self.inner.clone().dt().cast_time_unit(tu.0).into()
965
995
  }
966
996
 
967
- pub fn dt_cast_time_zone(&self, tz: String) -> Self {
968
- self.inner.clone().dt().cast_time_zone(tz).into()
997
+ pub fn dt_replace_time_zone(&self, tz: Option<String>) -> Self {
998
+ self.inner.clone().dt().replace_time_zone(tz).into()
969
999
  }
970
1000
 
1001
+ #[allow(deprecated)]
971
1002
  pub fn dt_tz_localize(&self, tz: String) -> Self {
972
1003
  self.inner.clone().dt().tz_localize(tz).into()
973
1004
  }
@@ -989,7 +1020,7 @@ impl RbExpr {
989
1020
  }
990
1021
 
991
1022
  pub fn reinterpret(&self, signed: bool) -> Self {
992
- let function = move |s: Series| reinterpret(&s, signed);
1023
+ let function = move |s: Series| reinterpret(&s, signed).map(Some);
993
1024
  let dt = if signed {
994
1025
  DataType::Int64
995
1026
  } else {
@@ -1391,7 +1422,7 @@ impl RbExpr {
1391
1422
  self.inner
1392
1423
  .clone()
1393
1424
  .map(
1394
- |s| Ok(s.to_physical_repr().into_owned()),
1425
+ |s| Ok(Some(s.to_physical_repr().into_owned())),
1395
1426
  GetOutput::map_dtype(|dt| dt.to_physical()),
1396
1427
  )
1397
1428
  .with_fmt("to_physical")
@@ -1428,44 +1459,67 @@ impl RbExpr {
1428
1459
  .into()
1429
1460
  }
1430
1461
 
1431
- pub fn ewm_mean(&self, alpha: f64, adjust: bool, min_periods: usize) -> Self {
1462
+ pub fn ewm_mean(
1463
+ &self,
1464
+ alpha: f64,
1465
+ adjust: bool,
1466
+ min_periods: usize,
1467
+ ignore_nulls: bool,
1468
+ ) -> Self {
1432
1469
  let options = EWMOptions {
1433
1470
  alpha,
1434
1471
  adjust,
1435
1472
  bias: false,
1436
1473
  min_periods,
1474
+ ignore_nulls,
1437
1475
  };
1438
1476
  self.inner.clone().ewm_mean(options).into()
1439
1477
  }
1440
1478
 
1441
- pub fn ewm_std(&self, alpha: f64, adjust: bool, bias: bool, min_periods: usize) -> Self {
1479
+ pub fn ewm_std(
1480
+ &self,
1481
+ alpha: f64,
1482
+ adjust: bool,
1483
+ bias: bool,
1484
+ min_periods: usize,
1485
+ ignore_nulls: bool,
1486
+ ) -> Self {
1442
1487
  let options = EWMOptions {
1443
1488
  alpha,
1444
1489
  adjust,
1445
1490
  bias,
1446
1491
  min_periods,
1492
+ ignore_nulls,
1447
1493
  };
1448
1494
  self.inner.clone().ewm_std(options).into()
1449
1495
  }
1450
1496
 
1451
- pub fn ewm_var(&self, alpha: f64, adjust: bool, bias: bool, min_periods: usize) -> Self {
1497
+ pub fn ewm_var(
1498
+ &self,
1499
+ alpha: f64,
1500
+ adjust: bool,
1501
+ bias: bool,
1502
+ min_periods: usize,
1503
+ ignore_nulls: bool,
1504
+ ) -> Self {
1452
1505
  let options = EWMOptions {
1453
1506
  alpha,
1454
1507
  adjust,
1455
1508
  bias,
1456
1509
  min_periods,
1510
+ ignore_nulls,
1457
1511
  };
1458
1512
  self.inner.clone().ewm_var(options).into()
1459
1513
  }
1460
1514
 
1461
1515
  pub fn extend_constant(&self, value: Wrap<AnyValue>, n: usize) -> Self {
1462
- let value = Value::from(value);
1516
+ let value = value.into_value();
1463
1517
  self.inner
1464
1518
  .clone()
1465
1519
  .apply(
1466
1520
  move |s| {
1467
1521
  let value = value.try_convert::<Wrap<AnyValue>>().unwrap().0;
1468
- s.extend_constant(value, n)
1522
+ s.extend_constant(value, n).map(Some)
1469
1523
  },
1470
1524
  GetOutput::same_type(),
1471
1525
  )
@@ -1,14 +1,15 @@
1
- use crate::{RbExpr, RbPolarsErr, RbResult};
1
+ use crate::{RArray, RbExpr, RbPolarsErr, RbResult};
2
2
 
3
3
  impl RbExpr {
4
- pub fn meta_pop(&self) -> Vec<RbExpr> {
5
- self.inner
6
- .clone()
7
- .meta()
8
- .pop()
9
- .into_iter()
10
- .map(RbExpr::from)
11
- .collect()
4
+ pub fn meta_pop(&self) -> RArray {
5
+ RArray::from_iter(
6
+ self.inner
7
+ .clone()
8
+ .meta()
9
+ .pop()
10
+ .into_iter()
11
+ .map(RbExpr::from),
12
+ )
12
13
  }
13
14
 
14
15
  pub fn meta_eq(&self, other: &RbExpr) -> bool {