polars-df 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }