polars-df 0.6.0 → 0.8.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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/Cargo.lock +597 -599
  4. data/Cargo.toml +1 -0
  5. data/README.md +8 -7
  6. data/ext/polars/Cargo.toml +20 -10
  7. data/ext/polars/src/batched_csv.rs +27 -28
  8. data/ext/polars/src/conversion.rs +135 -106
  9. data/ext/polars/src/dataframe.rs +140 -131
  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/categorical.rs +8 -1
  13. data/ext/polars/src/expr/datetime.rs +10 -12
  14. data/ext/polars/src/expr/general.rs +129 -286
  15. data/ext/polars/src/expr/list.rs +17 -9
  16. data/ext/polars/src/{expr.rs → expr/mod.rs} +4 -2
  17. data/ext/polars/src/expr/name.rs +44 -0
  18. data/ext/polars/src/expr/rolling.rs +201 -0
  19. data/ext/polars/src/expr/string.rs +94 -67
  20. data/ext/polars/src/file.rs +3 -3
  21. data/ext/polars/src/functions/aggregation.rs +35 -0
  22. data/ext/polars/src/functions/eager.rs +7 -31
  23. data/ext/polars/src/functions/io.rs +10 -10
  24. data/ext/polars/src/functions/lazy.rs +66 -41
  25. data/ext/polars/src/functions/meta.rs +30 -0
  26. data/ext/polars/src/functions/misc.rs +8 -0
  27. data/ext/polars/src/functions/mod.rs +5 -0
  28. data/ext/polars/src/functions/random.rs +6 -0
  29. data/ext/polars/src/functions/range.rs +41 -0
  30. data/ext/polars/src/functions/string_cache.rs +11 -0
  31. data/ext/polars/src/functions/whenthen.rs +7 -7
  32. data/ext/polars/src/lazyframe.rs +74 -60
  33. data/ext/polars/src/lib.rs +175 -91
  34. data/ext/polars/src/{apply → map}/dataframe.rs +29 -34
  35. data/ext/polars/src/{apply → map}/mod.rs +5 -5
  36. data/ext/polars/src/{apply → map}/series.rs +18 -22
  37. data/ext/polars/src/object.rs +0 -30
  38. data/ext/polars/src/on_startup.rs +32 -0
  39. data/ext/polars/src/rb_modules.rs +22 -7
  40. data/ext/polars/src/series/aggregation.rs +3 -0
  41. data/ext/polars/src/series/construction.rs +5 -5
  42. data/ext/polars/src/series/export.rs +4 -4
  43. data/ext/polars/src/{series.rs → series/mod.rs} +28 -45
  44. data/ext/polars/src/series/{set_at_idx.rs → scatter.rs} +38 -22
  45. data/ext/polars/src/sql.rs +46 -0
  46. data/ext/polars/src/utils.rs +1 -1
  47. data/lib/polars/config.rb +530 -0
  48. data/lib/polars/data_frame.rb +182 -145
  49. data/lib/polars/data_types.rb +4 -1
  50. data/lib/polars/date_time_expr.rb +23 -28
  51. data/lib/polars/date_time_name_space.rb +17 -37
  52. data/lib/polars/dynamic_group_by.rb +2 -2
  53. data/lib/polars/expr.rb +398 -110
  54. data/lib/polars/functions.rb +29 -37
  55. data/lib/polars/group_by.rb +38 -55
  56. data/lib/polars/io.rb +40 -5
  57. data/lib/polars/lazy_frame.rb +116 -89
  58. data/lib/polars/lazy_functions.rb +40 -68
  59. data/lib/polars/lazy_group_by.rb +7 -8
  60. data/lib/polars/list_expr.rb +12 -8
  61. data/lib/polars/list_name_space.rb +2 -2
  62. data/lib/polars/name_expr.rb +198 -0
  63. data/lib/polars/rolling_group_by.rb +2 -2
  64. data/lib/polars/series.rb +315 -43
  65. data/lib/polars/sql_context.rb +194 -0
  66. data/lib/polars/string_expr.rb +114 -60
  67. data/lib/polars/string_name_space.rb +19 -4
  68. data/lib/polars/struct_expr.rb +1 -1
  69. data/lib/polars/struct_name_space.rb +1 -1
  70. data/lib/polars/utils.rb +25 -13
  71. data/lib/polars/version.rb +1 -1
  72. data/lib/polars.rb +3 -0
  73. metadata +23 -11
  74. /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};
@@ -163,12 +162,71 @@ impl RbExpr {
163
162
  .into()
164
163
  }
165
164
 
165
+ pub fn cut(
166
+ &self,
167
+ breaks: Vec<f64>,
168
+ labels: Option<Vec<String>>,
169
+ left_closed: bool,
170
+ include_breaks: bool,
171
+ ) -> Self {
172
+ self.inner
173
+ .clone()
174
+ .cut(breaks, labels, left_closed, include_breaks)
175
+ .into()
176
+ }
177
+
178
+ pub fn qcut(
179
+ &self,
180
+ probs: Vec<f64>,
181
+ labels: Option<Vec<String>>,
182
+ left_closed: bool,
183
+ allow_duplicates: bool,
184
+ include_breaks: bool,
185
+ ) -> Self {
186
+ self.inner
187
+ .clone()
188
+ .qcut(probs, labels, left_closed, allow_duplicates, include_breaks)
189
+ .into()
190
+ }
191
+
192
+ pub fn qcut_uniform(
193
+ &self,
194
+ n_bins: usize,
195
+ labels: Option<Vec<String>>,
196
+ left_closed: bool,
197
+ allow_duplicates: bool,
198
+ include_breaks: bool,
199
+ ) -> Self {
200
+ self.inner
201
+ .clone()
202
+ .qcut_uniform(
203
+ n_bins,
204
+ labels,
205
+ left_closed,
206
+ allow_duplicates,
207
+ include_breaks,
208
+ )
209
+ .into()
210
+ }
211
+
212
+ pub fn rle(&self) -> Self {
213
+ self.inner.clone().rle().into()
214
+ }
215
+
216
+ pub fn rle_id(&self) -> Self {
217
+ self.inner.clone().rle_id().into()
218
+ }
219
+
166
220
  pub fn agg_groups(&self) -> Self {
167
- self.clone().inner.agg_groups().into()
221
+ self.inner.clone().agg_groups().into()
168
222
  }
169
223
 
170
224
  pub fn count(&self) -> Self {
171
- self.clone().inner.count().into()
225
+ self.inner.clone().count().into()
226
+ }
227
+
228
+ pub fn len(&self) -> Self {
229
+ self.inner.clone().len().into()
172
230
  }
173
231
 
174
232
  pub fn value_counts(&self, multithreaded: bool, sorted: bool) -> Self {
@@ -220,12 +278,20 @@ impl RbExpr {
220
278
  .into()
221
279
  }
222
280
 
223
- pub fn top_k(&self, k: usize) -> Self {
224
- self.inner.clone().top_k(k).into()
281
+ pub fn top_k(&self, k: &Self) -> Self {
282
+ self.inner.clone().top_k(k.inner.clone()).into()
283
+ }
284
+
285
+ pub fn bottom_k(&self, k: &Self) -> Self {
286
+ self.inner.clone().bottom_k(k.inner.clone()).into()
287
+ }
288
+
289
+ pub fn peak_min(&self) -> Self {
290
+ self.inner.clone().peak_min().into()
225
291
  }
226
292
 
227
- pub fn bottom_k(&self, k: usize) -> Self {
228
- self.inner.clone().bottom_k(k).into()
293
+ pub fn peak_max(&self) -> Self {
294
+ self.inner.clone().peak_max().into()
229
295
  }
230
296
 
231
297
  pub fn arg_max(&self) -> Self {
@@ -243,8 +309,8 @@ impl RbExpr {
243
309
  .into()
244
310
  }
245
311
 
246
- pub fn take(&self, idx: &RbExpr) -> Self {
247
- self.clone().inner.take(idx.inner.clone()).into()
312
+ pub fn gather(&self, idx: &RbExpr) -> Self {
313
+ self.clone().inner.gather(idx.inner.clone()).into()
248
314
  }
249
315
 
250
316
  pub fn sort_by(&self, by: RArray, reverse: Vec<bool>) -> RbResult<Self> {
@@ -260,14 +326,13 @@ impl RbExpr {
260
326
  self.clone().inner.forward_fill(limit).into()
261
327
  }
262
328
 
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()
329
+ pub fn shift(&self, n: &Self, fill_value: Option<&Self>) -> Self {
330
+ let expr = self.inner.clone();
331
+ let out = match fill_value {
332
+ Some(v) => expr.shift_and_fill(n.inner.clone(), v.inner.clone()),
333
+ None => expr.shift(n.inner.clone()),
334
+ };
335
+ out.into()
271
336
  }
272
337
 
273
338
  pub fn fill_null(&self, expr: &RbExpr) -> Self {
@@ -323,26 +388,30 @@ impl RbExpr {
323
388
  self.clone().inner.is_unique().into()
324
389
  }
325
390
 
326
- pub fn approx_unique(&self) -> Self {
327
- self.clone().inner.approx_unique().into()
391
+ pub fn approx_n_unique(&self) -> Self {
392
+ self.clone().inner.approx_n_unique().into()
393
+ }
394
+
395
+ pub fn is_first_distinct(&self) -> Self {
396
+ self.clone().inner.is_first_distinct().into()
328
397
  }
329
398
 
330
- pub fn is_first(&self) -> Self {
331
- self.clone().inner.is_first().into()
399
+ pub fn is_last_distinct(&self) -> Self {
400
+ self.clone().inner.is_last_distinct().into()
332
401
  }
333
402
 
334
403
  pub fn explode(&self) -> Self {
335
404
  self.clone().inner.explode().into()
336
405
  }
337
406
 
338
- pub fn take_every(&self, n: usize) -> Self {
407
+ pub fn gather_every(&self, n: usize, offset: usize) -> Self {
339
408
  self.clone()
340
409
  .inner
341
410
  .map(
342
- move |s: Series| Ok(Some(s.take_every(n))),
411
+ move |s: Series| Ok(Some(s.gather_every(n, offset))),
343
412
  GetOutput::same_type(),
344
413
  )
345
- .with_fmt("take_every")
414
+ .with_fmt("gather_every")
346
415
  .into()
347
416
  }
348
417
 
@@ -387,20 +456,15 @@ impl RbExpr {
387
456
  self.clone().inner.ceil().into()
388
457
  }
389
458
 
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()
459
+ pub fn clip(&self, min: Option<&Self>, max: Option<&Self>) -> Self {
460
+ let expr = self.inner.clone();
461
+ let out = match (min, max) {
462
+ (Some(min), Some(max)) => expr.clip(min.inner.clone(), max.inner.clone()),
463
+ (Some(min), None) => expr.clip_min(min.inner.clone()),
464
+ (None, Some(max)) => expr.clip_max(max.inner.clone()),
465
+ (None, None) => expr,
466
+ };
467
+ out.into()
404
468
  }
405
469
 
406
470
  pub fn abs(&self) -> Self {
@@ -492,20 +556,20 @@ impl RbExpr {
492
556
  self.clone().inner.pow(exponent.inner.clone()).into()
493
557
  }
494
558
 
495
- pub fn cumsum(&self, reverse: bool) -> Self {
496
- self.clone().inner.cumsum(reverse).into()
559
+ pub fn cum_sum(&self, reverse: bool) -> Self {
560
+ self.clone().inner.cum_sum(reverse).into()
497
561
  }
498
562
 
499
- pub fn cummax(&self, reverse: bool) -> Self {
500
- self.clone().inner.cummax(reverse).into()
563
+ pub fn cum_max(&self, reverse: bool) -> Self {
564
+ self.clone().inner.cum_max(reverse).into()
501
565
  }
502
566
 
503
- pub fn cummin(&self, reverse: bool) -> Self {
504
- self.clone().inner.cummin(reverse).into()
567
+ pub fn cum_min(&self, reverse: bool) -> Self {
568
+ self.clone().inner.cum_min(reverse).into()
505
569
  }
506
570
 
507
- pub fn cumprod(&self, reverse: bool) -> Self {
508
- self.clone().inner.cumprod(reverse).into()
571
+ pub fn cum_prod(&self, reverse: bool) -> Self {
572
+ self.clone().inner.cum_prod(reverse).into()
509
573
  }
510
574
 
511
575
  pub fn product(&self) -> Self {
@@ -541,33 +605,6 @@ impl RbExpr {
541
605
  self.inner.clone().mode().into()
542
606
  }
543
607
 
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
608
  pub fn exclude(&self, columns: Vec<String>) -> Self {
572
609
  self.inner.clone().exclude(columns).into()
573
610
  }
@@ -576,200 +613,6 @@ impl RbExpr {
576
613
  self.inner.clone().interpolate(method.0).into()
577
614
  }
578
615
 
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
616
  pub fn lower_bound(&self) -> Self {
774
617
  self.inner.clone().lower_bound().into()
775
618
  }
@@ -797,8 +640,8 @@ impl RbExpr {
797
640
  self.inner.clone().diff(n, null_behavior.0).into()
798
641
  }
799
642
 
800
- pub fn pct_change(&self, n: i64) -> Self {
801
- self.inner.clone().pct_change(n).into()
643
+ pub fn pct_change(&self, n: &Self) -> Self {
644
+ self.inner.clone().pct_change(n.inner.clone()).into()
802
645
  }
803
646
 
804
647
  pub fn skew(&self, bias: bool) -> Self {
@@ -813,8 +656,8 @@ impl RbExpr {
813
656
  self.inner.clone().reshape(&dims).into()
814
657
  }
815
658
 
816
- pub fn cumcount(&self, reverse: bool) -> Self {
817
- self.inner.clone().cumcount(reverse).into()
659
+ pub fn cum_count(&self, reverse: bool) -> Self {
660
+ self.inner.clone().cum_count(reverse).into()
818
661
  }
819
662
 
820
663
  pub fn to_physical(&self) -> Self {
@@ -828,35 +671,33 @@ impl RbExpr {
828
671
  .into()
829
672
  }
830
673
 
831
- pub fn shuffle(&self, seed: Option<u64>, fixed_seed: bool) -> Self {
832
- self.inner.clone().shuffle(seed, fixed_seed).into()
674
+ pub fn shuffle(&self, seed: Option<u64>) -> Self {
675
+ self.inner.clone().shuffle(seed).into()
833
676
  }
834
677
 
835
678
  pub fn sample_n(
836
679
  &self,
837
- n: usize,
680
+ n: &Self,
838
681
  with_replacement: bool,
839
682
  shuffle: bool,
840
683
  seed: Option<u64>,
841
- fixed_seed: bool,
842
684
  ) -> Self {
843
685
  self.inner
844
686
  .clone()
845
- .sample_n(n, with_replacement, shuffle, seed, fixed_seed)
687
+ .sample_n(n.inner.clone(), with_replacement, shuffle, seed)
846
688
  .into()
847
689
  }
848
690
 
849
691
  pub fn sample_frac(
850
692
  &self,
851
- frac: f64,
693
+ frac: &Self,
852
694
  with_replacement: bool,
853
695
  shuffle: bool,
854
696
  seed: Option<u64>,
855
- fixed_seed: bool,
856
697
  ) -> Self {
857
698
  self.inner
858
699
  .clone()
859
- .sample_frac(frac, with_replacement, shuffle, seed, fixed_seed)
700
+ .sample_frac(frac.inner.clone(), with_replacement, shuffle, seed)
860
701
  .into()
861
702
  }
862
703
 
@@ -915,11 +756,13 @@ impl RbExpr {
915
756
 
916
757
  pub fn extend_constant(&self, value: Wrap<AnyValue>, n: usize) -> Self {
917
758
  let value = value.into_value();
759
+ let value = Opaque::from(value);
918
760
  self.inner
919
761
  .clone()
920
762
  .apply(
921
763
  move |s| {
922
- let value = value.try_convert::<Wrap<AnyValue>>().unwrap().0;
764
+ let value = Ruby::get().unwrap().get_inner(value);
765
+ let value = Wrap::<AnyValue>::try_convert(value).unwrap().0;
923
766
  s.extend_constant(value, n).map(Some)
924
767
  },
925
768
  GetOutput::same_type(),
@@ -928,12 +771,12 @@ impl RbExpr {
928
771
  .into()
929
772
  }
930
773
 
931
- pub fn any(&self) -> Self {
932
- self.inner.clone().any().into()
774
+ pub fn any(&self, drop_nulls: bool) -> Self {
775
+ self.inner.clone().any(drop_nulls).into()
933
776
  }
934
777
 
935
- pub fn all(&self) -> Self {
936
- self.inner.clone().all().into()
778
+ pub fn all(&self, drop_nulls: bool) -> Self {
779
+ self.inner.clone().all(drop_nulls).into()
937
780
  }
938
781
 
939
782
  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
+ }