polars-df 0.6.0 → 0.8.0

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