polars-df 0.6.0 → 0.7.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/Cargo.lock +468 -538
  4. data/Cargo.toml +1 -0
  5. data/README.md +8 -7
  6. data/ext/polars/Cargo.toml +17 -10
  7. data/ext/polars/src/batched_csv.rs +26 -26
  8. data/ext/polars/src/conversion.rs +121 -93
  9. data/ext/polars/src/dataframe.rs +116 -71
  10. data/ext/polars/src/error.rs +0 -5
  11. data/ext/polars/src/expr/binary.rs +18 -6
  12. data/ext/polars/src/expr/datetime.rs +10 -12
  13. data/ext/polars/src/expr/general.rs +68 -284
  14. data/ext/polars/src/expr/list.rs +17 -9
  15. data/ext/polars/src/{expr.rs → expr/mod.rs} +4 -2
  16. data/ext/polars/src/expr/name.rs +44 -0
  17. data/ext/polars/src/expr/rolling.rs +196 -0
  18. data/ext/polars/src/expr/string.rs +85 -58
  19. data/ext/polars/src/file.rs +3 -3
  20. data/ext/polars/src/functions/aggregation.rs +35 -0
  21. data/ext/polars/src/functions/eager.rs +7 -31
  22. data/ext/polars/src/functions/io.rs +10 -10
  23. data/ext/polars/src/functions/lazy.rs +66 -41
  24. data/ext/polars/src/functions/meta.rs +30 -0
  25. data/ext/polars/src/functions/misc.rs +8 -0
  26. data/ext/polars/src/functions/mod.rs +5 -0
  27. data/ext/polars/src/functions/random.rs +6 -0
  28. data/ext/polars/src/functions/range.rs +46 -0
  29. data/ext/polars/src/functions/string_cache.rs +11 -0
  30. data/ext/polars/src/functions/whenthen.rs +7 -7
  31. data/ext/polars/src/lazyframe.rs +47 -42
  32. data/ext/polars/src/lib.rs +156 -72
  33. data/ext/polars/src/{apply → map}/dataframe.rs +28 -33
  34. data/ext/polars/src/{apply → map}/mod.rs +3 -3
  35. data/ext/polars/src/{apply → map}/series.rs +12 -16
  36. data/ext/polars/src/object.rs +1 -1
  37. data/ext/polars/src/rb_modules.rs +22 -7
  38. data/ext/polars/src/series/construction.rs +4 -4
  39. data/ext/polars/src/series/export.rs +2 -2
  40. data/ext/polars/src/series/set_at_idx.rs +33 -17
  41. data/ext/polars/src/series.rs +7 -27
  42. data/ext/polars/src/sql.rs +46 -0
  43. data/lib/polars/config.rb +530 -0
  44. data/lib/polars/data_frame.rb +115 -82
  45. data/lib/polars/date_time_expr.rb +13 -18
  46. data/lib/polars/date_time_name_space.rb +5 -25
  47. data/lib/polars/dynamic_group_by.rb +2 -2
  48. data/lib/polars/expr.rb +177 -94
  49. data/lib/polars/functions.rb +29 -37
  50. data/lib/polars/group_by.rb +38 -55
  51. data/lib/polars/io.rb +37 -2
  52. data/lib/polars/lazy_frame.rb +93 -66
  53. data/lib/polars/lazy_functions.rb +36 -48
  54. data/lib/polars/lazy_group_by.rb +7 -8
  55. data/lib/polars/list_expr.rb +12 -8
  56. data/lib/polars/list_name_space.rb +2 -2
  57. data/lib/polars/name_expr.rb +198 -0
  58. data/lib/polars/rolling_group_by.rb +2 -2
  59. data/lib/polars/series.rb +26 -13
  60. data/lib/polars/sql_context.rb +194 -0
  61. data/lib/polars/string_expr.rb +114 -60
  62. data/lib/polars/string_name_space.rb +19 -4
  63. data/lib/polars/utils.rb +12 -0
  64. data/lib/polars/version.rb +1 -1
  65. data/lib/polars.rb +3 -0
  66. metadata +18 -7
  67. /data/ext/polars/src/{apply → map}/lazy.rs +0 -0
@@ -1,12 +1,11 @@
1
- use magnus::{block::Proc, IntoValue, RArray, Value};
1
+ use magnus::{prelude::*, value::Opaque, IntoValue, RArray, Ruby, Value};
2
2
  use polars::lazy::dsl;
3
3
  use polars::prelude::*;
4
4
  use polars::series::ops::NullBehavior;
5
5
  use polars_core::series::IsSorted;
6
- use std::any::Any;
7
6
 
8
- use crate::apply::lazy::map_single;
9
7
  use crate::conversion::{parse_fill_null_strategy, Wrap};
8
+ use crate::map::lazy::map_single;
10
9
  use crate::rb_exprs_to_exprs;
11
10
  use crate::utils::reinterpret;
12
11
  use crate::{RbExpr, RbResult};
@@ -220,12 +219,20 @@ impl RbExpr {
220
219
  .into()
221
220
  }
222
221
 
223
- pub fn top_k(&self, k: usize) -> Self {
224
- self.inner.clone().top_k(k).into()
222
+ pub fn top_k(&self, k: &Self) -> Self {
223
+ self.inner.clone().top_k(k.inner.clone()).into()
225
224
  }
226
225
 
227
- pub fn bottom_k(&self, k: usize) -> Self {
228
- self.inner.clone().bottom_k(k).into()
226
+ pub fn bottom_k(&self, k: &Self) -> Self {
227
+ self.inner.clone().bottom_k(k.inner.clone()).into()
228
+ }
229
+
230
+ pub fn peak_min(&self) -> Self {
231
+ self.inner.clone().peak_min().into()
232
+ }
233
+
234
+ pub fn peak_max(&self) -> Self {
235
+ self.inner.clone().peak_max().into()
229
236
  }
230
237
 
231
238
  pub fn arg_max(&self) -> Self {
@@ -243,8 +250,8 @@ impl RbExpr {
243
250
  .into()
244
251
  }
245
252
 
246
- pub fn take(&self, idx: &RbExpr) -> Self {
247
- self.clone().inner.take(idx.inner.clone()).into()
253
+ pub fn gather(&self, idx: &RbExpr) -> Self {
254
+ self.clone().inner.gather(idx.inner.clone()).into()
248
255
  }
249
256
 
250
257
  pub fn sort_by(&self, by: RArray, reverse: Vec<bool>) -> RbResult<Self> {
@@ -260,14 +267,13 @@ impl RbExpr {
260
267
  self.clone().inner.forward_fill(limit).into()
261
268
  }
262
269
 
263
- pub fn shift(&self, periods: i64) -> Self {
264
- self.clone().inner.shift(periods).into()
265
- }
266
- pub fn shift_and_fill(&self, periods: i64, fill_value: &RbExpr) -> Self {
267
- self.clone()
268
- .inner
269
- .shift_and_fill(periods, fill_value.inner.clone())
270
- .into()
270
+ pub fn shift(&self, n: &Self, fill_value: Option<&Self>) -> Self {
271
+ let expr = self.inner.clone();
272
+ let out = match fill_value {
273
+ Some(v) => expr.shift_and_fill(n.inner.clone(), v.inner.clone()),
274
+ None => expr.shift(n.inner.clone()),
275
+ };
276
+ out.into()
271
277
  }
272
278
 
273
279
  pub fn fill_null(&self, expr: &RbExpr) -> Self {
@@ -323,26 +329,30 @@ impl RbExpr {
323
329
  self.clone().inner.is_unique().into()
324
330
  }
325
331
 
326
- pub fn approx_unique(&self) -> Self {
327
- self.clone().inner.approx_unique().into()
332
+ pub fn approx_n_unique(&self) -> Self {
333
+ self.clone().inner.approx_n_unique().into()
328
334
  }
329
335
 
330
- pub fn is_first(&self) -> Self {
331
- self.clone().inner.is_first().into()
336
+ pub fn is_first_distinct(&self) -> Self {
337
+ self.clone().inner.is_first_distinct().into()
338
+ }
339
+
340
+ pub fn is_last_distinct(&self) -> Self {
341
+ self.clone().inner.is_last_distinct().into()
332
342
  }
333
343
 
334
344
  pub fn explode(&self) -> Self {
335
345
  self.clone().inner.explode().into()
336
346
  }
337
347
 
338
- pub fn take_every(&self, n: usize) -> Self {
348
+ pub fn gather_every(&self, n: usize) -> Self {
339
349
  self.clone()
340
350
  .inner
341
351
  .map(
342
- move |s: Series| Ok(Some(s.take_every(n))),
352
+ move |s: Series| Ok(Some(s.gather_every(n))),
343
353
  GetOutput::same_type(),
344
354
  )
345
- .with_fmt("take_every")
355
+ .with_fmt("gather_every")
346
356
  .into()
347
357
  }
348
358
 
@@ -387,20 +397,15 @@ impl RbExpr {
387
397
  self.clone().inner.ceil().into()
388
398
  }
389
399
 
390
- pub fn clip(&self, min: Value, max: Value) -> Self {
391
- let min = min.try_convert::<Wrap<AnyValue>>().unwrap().0;
392
- let max = max.try_convert::<Wrap<AnyValue>>().unwrap().0;
393
- self.clone().inner.clip(min, max).into()
394
- }
395
-
396
- pub fn clip_min(&self, min: Value) -> Self {
397
- let min = min.try_convert::<Wrap<AnyValue>>().unwrap().0;
398
- self.clone().inner.clip_min(min).into()
399
- }
400
-
401
- pub fn clip_max(&self, max: Value) -> Self {
402
- let max = max.try_convert::<Wrap<AnyValue>>().unwrap().0;
403
- self.clone().inner.clip_max(max).into()
400
+ pub fn clip(&self, min: Option<&Self>, max: Option<&Self>) -> Self {
401
+ let expr = self.inner.clone();
402
+ let out = match (min, max) {
403
+ (Some(min), Some(max)) => expr.clip(min.inner.clone(), max.inner.clone()),
404
+ (Some(min), None) => expr.clip_min(min.inner.clone()),
405
+ (None, Some(max)) => expr.clip_max(max.inner.clone()),
406
+ (None, None) => expr,
407
+ };
408
+ out.into()
404
409
  }
405
410
 
406
411
  pub fn abs(&self) -> Self {
@@ -492,20 +497,20 @@ impl RbExpr {
492
497
  self.clone().inner.pow(exponent.inner.clone()).into()
493
498
  }
494
499
 
495
- pub fn cumsum(&self, reverse: bool) -> Self {
496
- self.clone().inner.cumsum(reverse).into()
500
+ pub fn cum_sum(&self, reverse: bool) -> Self {
501
+ self.clone().inner.cum_sum(reverse).into()
497
502
  }
498
503
 
499
- pub fn cummax(&self, reverse: bool) -> Self {
500
- self.clone().inner.cummax(reverse).into()
504
+ pub fn cum_max(&self, reverse: bool) -> Self {
505
+ self.clone().inner.cum_max(reverse).into()
501
506
  }
502
507
 
503
- pub fn cummin(&self, reverse: bool) -> Self {
504
- self.clone().inner.cummin(reverse).into()
508
+ pub fn cum_min(&self, reverse: bool) -> Self {
509
+ self.clone().inner.cum_min(reverse).into()
505
510
  }
506
511
 
507
- pub fn cumprod(&self, reverse: bool) -> Self {
508
- self.clone().inner.cumprod(reverse).into()
512
+ pub fn cum_prod(&self, reverse: bool) -> Self {
513
+ self.clone().inner.cum_prod(reverse).into()
509
514
  }
510
515
 
511
516
  pub fn product(&self) -> Self {
@@ -541,33 +546,6 @@ impl RbExpr {
541
546
  self.inner.clone().mode().into()
542
547
  }
543
548
 
544
- pub fn keep_name(&self) -> Self {
545
- self.inner.clone().keep_name().into()
546
- }
547
-
548
- pub fn prefix(&self, prefix: String) -> Self {
549
- self.inner.clone().prefix(&prefix).into()
550
- }
551
-
552
- pub fn suffix(&self, suffix: String) -> Self {
553
- self.inner.clone().suffix(&suffix).into()
554
- }
555
-
556
- pub fn map_alias(&self, lambda: Proc) -> Self {
557
- self.inner
558
- .clone()
559
- .map_alias(move |name| {
560
- let out = lambda.call::<_, String>((name,));
561
- match out {
562
- Ok(out) => Ok(out),
563
- Err(e) => Err(PolarsError::ComputeError(
564
- format!("Ruby function in 'map_alias' produced an error: {}.", e).into(),
565
- )),
566
- }
567
- })
568
- .into()
569
- }
570
-
571
549
  pub fn exclude(&self, columns: Vec<String>) -> Self {
572
550
  self.inner.clone().exclude(columns).into()
573
551
  }
@@ -576,200 +554,6 @@ impl RbExpr {
576
554
  self.inner.clone().interpolate(method.0).into()
577
555
  }
578
556
 
579
- pub fn rolling_sum(
580
- &self,
581
- window_size: String,
582
- weights: Option<Vec<f64>>,
583
- min_periods: usize,
584
- center: bool,
585
- by: Option<String>,
586
- closed: Option<Wrap<ClosedWindow>>,
587
- ) -> Self {
588
- let options = RollingOptions {
589
- window_size: Duration::parse(&window_size),
590
- weights,
591
- min_periods,
592
- center,
593
- by,
594
- closed_window: closed.map(|c| c.0),
595
- ..Default::default()
596
- };
597
- self.inner.clone().rolling_sum(options).into()
598
- }
599
-
600
- pub fn rolling_min(
601
- &self,
602
- window_size: String,
603
- weights: Option<Vec<f64>>,
604
- min_periods: usize,
605
- center: bool,
606
- by: Option<String>,
607
- closed: Option<Wrap<ClosedWindow>>,
608
- ) -> Self {
609
- let options = RollingOptions {
610
- window_size: Duration::parse(&window_size),
611
- weights,
612
- min_periods,
613
- center,
614
- by,
615
- closed_window: closed.map(|c| c.0),
616
- ..Default::default()
617
- };
618
- self.inner.clone().rolling_min(options).into()
619
- }
620
-
621
- pub fn rolling_max(
622
- &self,
623
- window_size: String,
624
- weights: Option<Vec<f64>>,
625
- min_periods: usize,
626
- center: bool,
627
- by: Option<String>,
628
- closed: Option<Wrap<ClosedWindow>>,
629
- ) -> Self {
630
- let options = RollingOptions {
631
- window_size: Duration::parse(&window_size),
632
- weights,
633
- min_periods,
634
- center,
635
- by,
636
- closed_window: closed.map(|c| c.0),
637
- ..Default::default()
638
- };
639
- self.inner.clone().rolling_max(options).into()
640
- }
641
-
642
- pub fn rolling_mean(
643
- &self,
644
- window_size: String,
645
- weights: Option<Vec<f64>>,
646
- min_periods: usize,
647
- center: bool,
648
- by: Option<String>,
649
- closed: Option<Wrap<ClosedWindow>>,
650
- ) -> Self {
651
- let options = RollingOptions {
652
- window_size: Duration::parse(&window_size),
653
- weights,
654
- min_periods,
655
- center,
656
- by,
657
- closed_window: closed.map(|c| c.0),
658
- ..Default::default()
659
- };
660
-
661
- self.inner.clone().rolling_mean(options).into()
662
- }
663
-
664
- #[allow(clippy::too_many_arguments)]
665
- pub fn rolling_std(
666
- &self,
667
- window_size: String,
668
- weights: Option<Vec<f64>>,
669
- min_periods: usize,
670
- center: bool,
671
- by: Option<String>,
672
- closed: Option<Wrap<ClosedWindow>>,
673
- ddof: u8,
674
- ) -> Self {
675
- let options = RollingOptions {
676
- window_size: Duration::parse(&window_size),
677
- weights,
678
- min_periods,
679
- center,
680
- by,
681
- closed_window: closed.map(|c| c.0),
682
- fn_params: Some(Arc::new(RollingVarParams { ddof }) as Arc<dyn Any + Send + Sync>),
683
- };
684
-
685
- self.inner.clone().rolling_std(options).into()
686
- }
687
-
688
- #[allow(clippy::too_many_arguments)]
689
- pub fn rolling_var(
690
- &self,
691
- window_size: String,
692
- weights: Option<Vec<f64>>,
693
- min_periods: usize,
694
- center: bool,
695
- by: Option<String>,
696
- closed: Option<Wrap<ClosedWindow>>,
697
- ddof: u8,
698
- ) -> Self {
699
- let options = RollingOptions {
700
- window_size: Duration::parse(&window_size),
701
- weights,
702
- min_periods,
703
- center,
704
- by,
705
- closed_window: closed.map(|c| c.0),
706
- fn_params: Some(Arc::new(RollingVarParams { ddof }) as Arc<dyn Any + Send + Sync>),
707
- };
708
-
709
- self.inner.clone().rolling_var(options).into()
710
- }
711
-
712
- pub fn rolling_median(
713
- &self,
714
- window_size: String,
715
- weights: Option<Vec<f64>>,
716
- min_periods: usize,
717
- center: bool,
718
- by: Option<String>,
719
- closed: Option<Wrap<ClosedWindow>>,
720
- ) -> Self {
721
- let options = RollingOptions {
722
- window_size: Duration::parse(&window_size),
723
- weights,
724
- min_periods,
725
- center,
726
- by,
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>),
732
- };
733
- self.inner.clone().rolling_quantile(options).into()
734
- }
735
-
736
- #[allow(clippy::too_many_arguments)]
737
- pub fn rolling_quantile(
738
- &self,
739
- quantile: f64,
740
- interpolation: Wrap<QuantileInterpolOptions>,
741
- window_size: String,
742
- weights: Option<Vec<f64>>,
743
- min_periods: usize,
744
- center: bool,
745
- by: Option<String>,
746
- closed: Option<Wrap<ClosedWindow>>,
747
- ) -> Self {
748
- let options = RollingOptions {
749
- window_size: Duration::parse(&window_size),
750
- weights,
751
- min_periods,
752
- center,
753
- by,
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>),
759
- };
760
-
761
- self.inner.clone().rolling_quantile(options).into()
762
- }
763
-
764
- pub fn rolling_skew(&self, window_size: usize, bias: bool) -> Self {
765
- self.inner
766
- .clone()
767
- .rolling_apply_float(window_size, move |ca| {
768
- ca.clone().into_series().skew(bias).unwrap()
769
- })
770
- .into()
771
- }
772
-
773
557
  pub fn lower_bound(&self) -> Self {
774
558
  self.inner.clone().lower_bound().into()
775
559
  }
@@ -797,8 +581,8 @@ impl RbExpr {
797
581
  self.inner.clone().diff(n, null_behavior.0).into()
798
582
  }
799
583
 
800
- pub fn pct_change(&self, n: i64) -> Self {
801
- self.inner.clone().pct_change(n).into()
584
+ pub fn pct_change(&self, n: &Self) -> Self {
585
+ self.inner.clone().pct_change(n.inner.clone()).into()
802
586
  }
803
587
 
804
588
  pub fn skew(&self, bias: bool) -> Self {
@@ -813,8 +597,8 @@ impl RbExpr {
813
597
  self.inner.clone().reshape(&dims).into()
814
598
  }
815
599
 
816
- pub fn cumcount(&self, reverse: bool) -> Self {
817
- self.inner.clone().cumcount(reverse).into()
600
+ pub fn cum_count(&self, reverse: bool) -> Self {
601
+ self.inner.clone().cum_count(reverse).into()
818
602
  }
819
603
 
820
604
  pub fn to_physical(&self) -> Self {
@@ -828,35 +612,33 @@ impl RbExpr {
828
612
  .into()
829
613
  }
830
614
 
831
- pub fn shuffle(&self, seed: Option<u64>, fixed_seed: bool) -> Self {
832
- self.inner.clone().shuffle(seed, fixed_seed).into()
615
+ pub fn shuffle(&self, seed: Option<u64>) -> Self {
616
+ self.inner.clone().shuffle(seed).into()
833
617
  }
834
618
 
835
619
  pub fn sample_n(
836
620
  &self,
837
- n: usize,
621
+ n: &Self,
838
622
  with_replacement: bool,
839
623
  shuffle: bool,
840
624
  seed: Option<u64>,
841
- fixed_seed: bool,
842
625
  ) -> Self {
843
626
  self.inner
844
627
  .clone()
845
- .sample_n(n, with_replacement, shuffle, seed, fixed_seed)
628
+ .sample_n(n.inner.clone(), with_replacement, shuffle, seed)
846
629
  .into()
847
630
  }
848
631
 
849
632
  pub fn sample_frac(
850
633
  &self,
851
- frac: f64,
634
+ frac: &Self,
852
635
  with_replacement: bool,
853
636
  shuffle: bool,
854
637
  seed: Option<u64>,
855
- fixed_seed: bool,
856
638
  ) -> Self {
857
639
  self.inner
858
640
  .clone()
859
- .sample_frac(frac, with_replacement, shuffle, seed, fixed_seed)
641
+ .sample_frac(frac.inner.clone(), with_replacement, shuffle, seed)
860
642
  .into()
861
643
  }
862
644
 
@@ -915,11 +697,13 @@ impl RbExpr {
915
697
 
916
698
  pub fn extend_constant(&self, value: Wrap<AnyValue>, n: usize) -> Self {
917
699
  let value = value.into_value();
700
+ let value = Opaque::from(value);
918
701
  self.inner
919
702
  .clone()
920
703
  .apply(
921
704
  move |s| {
922
- let value = value.try_convert::<Wrap<AnyValue>>().unwrap().0;
705
+ let value = Ruby::get().unwrap().get_inner(value);
706
+ let value = Wrap::<AnyValue>::try_convert(value).unwrap().0;
923
707
  s.extend_constant(value, n).map(Some)
924
708
  },
925
709
  GetOutput::same_type(),
@@ -928,12 +712,12 @@ impl RbExpr {
928
712
  .into()
929
713
  }
930
714
 
931
- pub fn any(&self) -> Self {
932
- self.inner.clone().any().into()
715
+ pub fn any(&self, drop_nulls: bool) -> Self {
716
+ self.inner.clone().any(drop_nulls).into()
933
717
  }
934
718
 
935
- pub fn all(&self) -> Self {
936
- self.inner.clone().all().into()
719
+ pub fn all(&self, drop_nulls: bool) -> Self {
720
+ self.inner.clone().all(drop_nulls).into()
937
721
  }
938
722
 
939
723
  pub fn log(&self, base: f64) -> Self {
@@ -23,11 +23,11 @@ impl RbExpr {
23
23
  .into()
24
24
  }
25
25
 
26
- pub fn list_count_match(&self, expr: &RbExpr) -> Self {
26
+ pub fn list_count_matches(&self, expr: &RbExpr) -> Self {
27
27
  self.inner
28
28
  .clone()
29
29
  .list()
30
- .count_match(expr.inner.clone())
30
+ .count_matches(expr.inner.clone())
31
31
  .into()
32
32
  }
33
33
 
@@ -47,12 +47,16 @@ impl RbExpr {
47
47
  self.inner.clone().list().get(index.inner.clone()).into()
48
48
  }
49
49
 
50
- pub fn list_join(&self, separator: String) -> Self {
51
- self.inner.clone().list().join(&separator).into()
50
+ pub fn list_join(&self, separator: &RbExpr) -> Self {
51
+ self.inner
52
+ .clone()
53
+ .list()
54
+ .join(separator.inner.clone())
55
+ .into()
52
56
  }
53
57
 
54
- pub fn list_lengths(&self) -> Self {
55
- self.inner.clone().list().lengths().into()
58
+ pub fn list_len(&self) -> Self {
59
+ self.inner.clone().list().len().into()
56
60
  }
57
61
 
58
62
  pub fn list_max(&self) -> Self {
@@ -76,8 +80,12 @@ impl RbExpr {
76
80
  self.inner.clone().list().reverse().into()
77
81
  }
78
82
 
79
- pub fn list_shift(&self, periods: i64) -> Self {
80
- self.inner.clone().list().shift(periods).into()
83
+ pub fn list_shift(&self, periods: &RbExpr) -> Self {
84
+ self.inner
85
+ .clone()
86
+ .list()
87
+ .shift(periods.inner.clone())
88
+ .into()
81
89
  }
82
90
 
83
91
  pub fn list_slice(&self, offset: &RbExpr, length: Option<&RbExpr>) -> Self {
@@ -127,7 +135,7 @@ impl RbExpr {
127
135
  // let name_gen = name_gen.map(|lambda| {
128
136
  // Arc::new(move |idx: usize| {
129
137
  // let out: Value = lambda.funcall("call", (idx,)).unwrap();
130
- // out.try_convert::<String>().unwrap()
138
+ // String::try_convert(out).unwrap()
131
139
  // }) as NameGenerator
132
140
  // });
133
141
 
@@ -5,10 +5,12 @@ mod datetime;
5
5
  mod general;
6
6
  mod list;
7
7
  mod meta;
8
+ mod name;
9
+ mod rolling;
8
10
  mod string;
9
11
  mod r#struct;
10
12
 
11
- use magnus::RArray;
13
+ use magnus::{prelude::*, RArray};
12
14
  use polars::lazy::dsl::Expr;
13
15
 
14
16
  use crate::RbResult;
@@ -28,7 +30,7 @@ impl From<Expr> for RbExpr {
28
30
  pub fn rb_exprs_to_exprs(rb_exprs: RArray) -> RbResult<Vec<Expr>> {
29
31
  let mut exprs = Vec::new();
30
32
  for item in rb_exprs.each() {
31
- exprs.push(item?.try_convert::<&RbExpr>()?.inner.clone());
33
+ exprs.push(<&RbExpr>::try_convert(item?)?.inner.clone());
32
34
  }
33
35
  Ok(exprs)
34
36
  }
@@ -0,0 +1,44 @@
1
+ use magnus::{block::Proc, value::Opaque, Ruby};
2
+ use polars::prelude::*;
3
+
4
+ use crate::RbExpr;
5
+
6
+ impl RbExpr {
7
+ pub fn name_keep(&self) -> Self {
8
+ self.inner.clone().name().keep().into()
9
+ }
10
+
11
+ pub fn name_map(&self, lambda: Proc) -> Self {
12
+ let lambda = Opaque::from(lambda);
13
+ self.inner
14
+ .clone()
15
+ .name()
16
+ .map(move |name| {
17
+ let lambda = Ruby::get().unwrap().get_inner(lambda);
18
+ let out = lambda.call::<_, String>((name,));
19
+ match out {
20
+ Ok(out) => Ok(out),
21
+ Err(e) => Err(PolarsError::ComputeError(
22
+ format!("Ruby function in 'name.map' produced an error: {}.", e).into(),
23
+ )),
24
+ }
25
+ })
26
+ .into()
27
+ }
28
+
29
+ pub fn name_prefix(&self, prefix: String) -> Self {
30
+ self.inner.clone().name().prefix(&prefix).into()
31
+ }
32
+
33
+ pub fn name_suffix(&self, suffix: String) -> Self {
34
+ self.inner.clone().name().suffix(&suffix).into()
35
+ }
36
+
37
+ pub fn name_to_lowercase(&self) -> Self {
38
+ self.inner.clone().name().to_lowercase().into()
39
+ }
40
+
41
+ pub fn name_to_uppercase(&self) -> Self {
42
+ self.inner.clone().name().to_uppercase().into()
43
+ }
44
+ }