polars-df 0.8.0-x86_64-linux → 0.10.0-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -1
  3. data/Cargo.lock +159 -66
  4. data/Cargo.toml +0 -3
  5. data/LICENSE-THIRD-PARTY.txt +3112 -1613
  6. data/LICENSE.txt +1 -1
  7. data/README.md +3 -2
  8. data/lib/polars/3.1/polars.so +0 -0
  9. data/lib/polars/3.2/polars.so +0 -0
  10. data/lib/polars/3.3/polars.so +0 -0
  11. data/lib/polars/array_expr.rb +453 -0
  12. data/lib/polars/array_name_space.rb +346 -0
  13. data/lib/polars/batched_csv_reader.rb +4 -2
  14. data/lib/polars/cat_expr.rb +24 -0
  15. data/lib/polars/cat_name_space.rb +75 -0
  16. data/lib/polars/config.rb +2 -2
  17. data/lib/polars/data_frame.rb +306 -96
  18. data/lib/polars/data_types.rb +191 -28
  19. data/lib/polars/date_time_expr.rb +41 -18
  20. data/lib/polars/date_time_name_space.rb +9 -3
  21. data/lib/polars/exceptions.rb +12 -1
  22. data/lib/polars/expr.rb +898 -215
  23. data/lib/polars/functions/aggregation/horizontal.rb +246 -0
  24. data/lib/polars/functions/aggregation/vertical.rb +282 -0
  25. data/lib/polars/functions/as_datatype.rb +248 -0
  26. data/lib/polars/functions/col.rb +47 -0
  27. data/lib/polars/functions/eager.rb +182 -0
  28. data/lib/polars/functions/lazy.rb +1280 -0
  29. data/lib/polars/functions/len.rb +49 -0
  30. data/lib/polars/functions/lit.rb +35 -0
  31. data/lib/polars/functions/random.rb +16 -0
  32. data/lib/polars/functions/range/date_range.rb +103 -0
  33. data/lib/polars/functions/range/int_range.rb +51 -0
  34. data/lib/polars/functions/repeat.rb +144 -0
  35. data/lib/polars/functions/whenthen.rb +96 -0
  36. data/lib/polars/functions.rb +29 -416
  37. data/lib/polars/group_by.rb +2 -2
  38. data/lib/polars/io.rb +36 -31
  39. data/lib/polars/lazy_frame.rb +405 -88
  40. data/lib/polars/list_expr.rb +158 -8
  41. data/lib/polars/list_name_space.rb +102 -0
  42. data/lib/polars/meta_expr.rb +175 -7
  43. data/lib/polars/series.rb +282 -41
  44. data/lib/polars/string_cache.rb +75 -0
  45. data/lib/polars/string_expr.rb +413 -96
  46. data/lib/polars/string_name_space.rb +4 -4
  47. data/lib/polars/testing.rb +507 -0
  48. data/lib/polars/utils.rb +106 -8
  49. data/lib/polars/version.rb +1 -1
  50. data/lib/polars/whenthen.rb +83 -0
  51. data/lib/polars.rb +16 -4
  52. metadata +34 -6
  53. data/lib/polars/lazy_functions.rb +0 -1181
  54. data/lib/polars/when.rb +0 -16
  55. data/lib/polars/when_then.rb +0 -19
data/lib/polars/expr.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  module Polars
2
2
  # Expressions that can be used in various contexts.
3
3
  class Expr
4
+ # @private
5
+ NO_DEFAULT = Object.new
6
+
4
7
  # @private
5
8
  attr_accessor :_rbexpr
6
9
 
@@ -23,112 +26,106 @@ module Polars
23
26
  #
24
27
  # @return [Expr]
25
28
  def ^(other)
26
- wrap_expr(_rbexpr._xor(_to_rbexpr(other)))
29
+ _from_rbexpr(_rbexpr._xor(_to_rbexpr(other)))
27
30
  end
28
31
 
29
32
  # Bitwise AND.
30
33
  #
31
34
  # @return [Expr]
32
35
  def &(other)
33
- wrap_expr(_rbexpr._and(_to_rbexpr(other)))
36
+ _from_rbexpr(_rbexpr._and(_to_rbexpr(other)))
34
37
  end
35
38
 
36
39
  # Bitwise OR.
37
40
  #
38
41
  # @return [Expr]
39
42
  def |(other)
40
- wrap_expr(_rbexpr._or(_to_rbexpr(other)))
43
+ _from_rbexpr(_rbexpr._or(_to_rbexpr(other)))
41
44
  end
42
45
 
43
46
  # Performs addition.
44
47
  #
45
48
  # @return [Expr]
46
49
  def +(other)
47
- wrap_expr(_rbexpr + _to_rbexpr(other))
50
+ _from_rbexpr(_rbexpr + _to_rbexpr(other))
48
51
  end
49
52
 
50
53
  # Performs subtraction.
51
54
  #
52
55
  # @return [Expr]
53
56
  def -(other)
54
- wrap_expr(_rbexpr - _to_rbexpr(other))
57
+ _from_rbexpr(_rbexpr - _to_rbexpr(other))
55
58
  end
56
59
 
57
60
  # Performs multiplication.
58
61
  #
59
62
  # @return [Expr]
60
63
  def *(other)
61
- wrap_expr(_rbexpr * _to_rbexpr(other))
64
+ _from_rbexpr(_rbexpr * _to_rbexpr(other))
62
65
  end
63
66
 
64
67
  # Performs division.
65
68
  #
66
69
  # @return [Expr]
67
70
  def /(other)
68
- wrap_expr(_rbexpr / _to_rbexpr(other))
69
- end
70
-
71
- # Performs floor division.
72
- #
73
- # @return [Expr]
74
- def floordiv(other)
75
- wrap_expr(_rbexpr.floordiv(_to_rbexpr(other)))
71
+ _from_rbexpr(_rbexpr / _to_rbexpr(other))
76
72
  end
77
73
 
78
74
  # Returns the modulo.
79
75
  #
80
76
  # @return [Expr]
81
77
  def %(other)
82
- wrap_expr(_rbexpr % _to_rbexpr(other))
78
+ _from_rbexpr(_rbexpr % _to_rbexpr(other))
83
79
  end
84
80
 
85
81
  # Raises to the power of exponent.
86
82
  #
87
83
  # @return [Expr]
88
84
  def **(power)
89
- pow(power)
85
+ exponent = Utils.expr_to_lit_or_expr(power)
86
+ _from_rbexpr(_rbexpr.pow(exponent._rbexpr))
90
87
  end
91
88
 
92
89
  # Greater than or equal.
93
90
  #
94
91
  # @return [Expr]
95
92
  def >=(other)
96
- wrap_expr(_rbexpr.gt_eq(_to_expr(other)._rbexpr))
93
+ _from_rbexpr(_rbexpr.gt_eq(_to_expr(other)._rbexpr))
97
94
  end
98
95
 
99
96
  # Less than or equal.
100
97
  #
101
98
  # @return [Expr]
102
99
  def <=(other)
103
- wrap_expr(_rbexpr.lt_eq(_to_expr(other)._rbexpr))
100
+ _from_rbexpr(_rbexpr.lt_eq(_to_expr(other)._rbexpr))
104
101
  end
105
102
 
106
103
  # Equal.
107
104
  #
108
105
  # @return [Expr]
109
106
  def ==(other)
110
- wrap_expr(_rbexpr.eq(_to_expr(other)._rbexpr))
107
+ _from_rbexpr(_rbexpr.eq(_to_expr(other)._rbexpr))
111
108
  end
112
109
 
113
110
  # Not equal.
114
111
  #
115
112
  # @return [Expr]
116
113
  def !=(other)
117
- wrap_expr(_rbexpr.neq(_to_expr(other)._rbexpr))
114
+ _from_rbexpr(_rbexpr.neq(_to_expr(other)._rbexpr))
118
115
  end
119
116
 
120
117
  # Less than.
121
118
  #
122
119
  # @return [Expr]
123
120
  def <(other)
124
- wrap_expr(_rbexpr.lt(_to_expr(other)._rbexpr))
121
+ _from_rbexpr(_rbexpr.lt(_to_expr(other)._rbexpr))
125
122
  end
126
123
 
127
124
  # Greater than.
128
125
  #
129
126
  # @return [Expr]
130
127
  def >(other)
131
- wrap_expr(_rbexpr.gt(_to_expr(other)._rbexpr))
128
+ _from_rbexpr(_rbexpr.gt(_to_expr(other)._rbexpr))
132
129
  end
133
130
 
134
131
  # Performs boolean not.
@@ -142,7 +139,7 @@ module Polars
142
139
  #
143
140
  # @return [Expr]
144
141
  def -@
145
- Utils.lit(0) - self
142
+ _from_rbexpr(_rbexpr.neg)
146
143
  end
147
144
 
148
145
  # Cast to physical representation of the logical dtype.
@@ -179,7 +176,7 @@ module Polars
179
176
  # # │ a ┆ 0 │
180
177
  # # └──────┴───────────────┘
181
178
  def to_physical
182
- wrap_expr(_rbexpr.to_physical)
179
+ _from_rbexpr(_rbexpr.to_physical)
183
180
  end
184
181
 
185
182
  # Check if any boolean value in a Boolean column is `true`.
@@ -199,7 +196,7 @@ module Polars
199
196
  # # │ true ┆ false │
200
197
  # # └──────┴───────┘
201
198
  def any(drop_nulls: true)
202
- wrap_expr(_rbexpr.any(drop_nulls))
199
+ _from_rbexpr(_rbexpr.any(drop_nulls))
203
200
  end
204
201
 
205
202
  # Check if all boolean values in a Boolean column are `true`.
@@ -224,7 +221,7 @@ module Polars
224
221
  # # │ true ┆ false ┆ false │
225
222
  # # └──────┴───────┴───────┘
226
223
  def all(drop_nulls: true)
227
- wrap_expr(_rbexpr.all(drop_nulls))
224
+ _from_rbexpr(_rbexpr.all(drop_nulls))
228
225
  end
229
226
 
230
227
  # Compute the square root of the elements.
@@ -290,7 +287,7 @@ module Polars
290
287
  # # │ 54.59815 │
291
288
  # # └──────────┘
292
289
  def exp
293
- wrap_expr(_rbexpr.exp)
290
+ _from_rbexpr(_rbexpr.exp)
294
291
  end
295
292
 
296
293
  # Rename the output of an expression.
@@ -325,7 +322,7 @@ module Polars
325
322
  # # │ 3 ┆ null │
326
323
  # # └─────┴──────┘
327
324
  def alias(name)
328
- wrap_expr(_rbexpr._alias(name))
325
+ _from_rbexpr(_rbexpr._alias(name))
329
326
  end
330
327
 
331
328
  # TODO support symbols for exclude
@@ -368,10 +365,10 @@ module Polars
368
365
  def exclude(columns)
369
366
  if columns.is_a?(::String)
370
367
  columns = [columns]
371
- return wrap_expr(_rbexpr.exclude(columns))
368
+ return _from_rbexpr(_rbexpr.exclude(columns))
372
369
  elsif !columns.is_a?(::Array)
373
370
  columns = [columns]
374
- return wrap_expr(_rbexpr.exclude_dtype(columns))
371
+ return _from_rbexpr(_rbexpr.exclude_dtype(columns))
375
372
  end
376
373
 
377
374
  if !columns.all? { |a| a.is_a?(::String) } || !columns.all? { |a| Utils.is_polars_dtype(a) }
@@ -379,9 +376,9 @@ module Polars
379
376
  end
380
377
 
381
378
  if columns[0].is_a?(::String)
382
- wrap_expr(_rbexpr.exclude(columns))
379
+ _from_rbexpr(_rbexpr.exclude(columns))
383
380
  else
384
- wrap_expr(_rbexpr.exclude_dtype(columns))
381
+ _from_rbexpr(_rbexpr.exclude_dtype(columns))
385
382
  end
386
383
  end
387
384
 
@@ -490,8 +487,9 @@ module Polars
490
487
  # # │ true │
491
488
  # # └───────┘
492
489
  def is_not
493
- wrap_expr(_rbexpr.is_not)
490
+ _from_rbexpr(_rbexpr.not_)
494
491
  end
492
+ alias_method :not_, :is_not
495
493
 
496
494
  # Returns a boolean Series indicating which values are null.
497
495
  #
@@ -519,7 +517,7 @@ module Polars
519
517
  # # │ 5 ┆ 5.0 ┆ false ┆ false │
520
518
  # # └──────┴─────┴──────────┴──────────┘
521
519
  def is_null
522
- wrap_expr(_rbexpr.is_null)
520
+ _from_rbexpr(_rbexpr.is_null)
523
521
  end
524
522
 
525
523
  # Returns a boolean Series indicating which values are not null.
@@ -548,7 +546,7 @@ module Polars
548
546
  # # │ 5 ┆ 5.0 ┆ true ┆ true │
549
547
  # # └──────┴─────┴────────────┴────────────┘
550
548
  def is_not_null
551
- wrap_expr(_rbexpr.is_not_null)
549
+ _from_rbexpr(_rbexpr.is_not_null)
552
550
  end
553
551
 
554
552
  # Returns a boolean Series indicating which values are finite.
@@ -574,7 +572,7 @@ module Polars
574
572
  # # │ true ┆ false │
575
573
  # # └──────┴───────┘
576
574
  def is_finite
577
- wrap_expr(_rbexpr.is_finite)
575
+ _from_rbexpr(_rbexpr.is_finite)
578
576
  end
579
577
 
580
578
  # Returns a boolean Series indicating which values are infinite.
@@ -600,7 +598,7 @@ module Polars
600
598
  # # │ false ┆ true │
601
599
  # # └───────┴───────┘
602
600
  def is_infinite
603
- wrap_expr(_rbexpr.is_infinite)
601
+ _from_rbexpr(_rbexpr.is_infinite)
604
602
  end
605
603
 
606
604
  # Returns a boolean Series indicating which values are NaN.
@@ -633,7 +631,7 @@ module Polars
633
631
  # # │ 5 ┆ 5.0 ┆ false │
634
632
  # # └──────┴─────┴─────────┘
635
633
  def is_nan
636
- wrap_expr(_rbexpr.is_nan)
634
+ _from_rbexpr(_rbexpr.is_nan)
637
635
  end
638
636
 
639
637
  # Returns a boolean Series indicating which values are not NaN.
@@ -666,7 +664,7 @@ module Polars
666
664
  # # │ 5 ┆ 5.0 ┆ true │
667
665
  # # └──────┴─────┴──────────────┘
668
666
  def is_not_nan
669
- wrap_expr(_rbexpr.is_not_nan)
667
+ _from_rbexpr(_rbexpr.is_not_nan)
670
668
  end
671
669
 
672
670
  # Get the group indexes of the group by operation.
@@ -701,7 +699,7 @@ module Polars
701
699
  # # │ two ┆ [3, 4, 5] │
702
700
  # # └───────┴───────────┘
703
701
  def agg_groups
704
- wrap_expr(_rbexpr.agg_groups)
702
+ _from_rbexpr(_rbexpr.agg_groups)
705
703
  end
706
704
 
707
705
  # Count the number of values in this expression.
@@ -718,12 +716,10 @@ module Polars
718
716
  # # │ --- ┆ --- │
719
717
  # # │ u32 ┆ u32 │
720
718
  # # ╞═════╪═════╡
721
- # # │ 3 ┆ 3
719
+ # # │ 3 ┆ 2
722
720
  # # └─────┴─────┘
723
721
  def count
724
- warn "`Expr#count` will exclude null values in 0.9.0. Use `Expr#length` instead."
725
- # wrap_expr(_rbexpr.count)
726
- wrap_expr(_rbexpr.len)
722
+ _from_rbexpr(_rbexpr.count)
727
723
  end
728
724
 
729
725
  # Count the number of values in this expression.
@@ -743,7 +739,7 @@ module Polars
743
739
  # # │ 3 ┆ 3 │
744
740
  # # └─────┴─────┘
745
741
  def len
746
- wrap_expr(_rbexpr.len)
742
+ _from_rbexpr(_rbexpr.len)
747
743
  end
748
744
  alias_method :length, :len
749
745
 
@@ -782,7 +778,7 @@ module Polars
782
778
  if !length.is_a?(Expr)
783
779
  length = Polars.lit(length)
784
780
  end
785
- wrap_expr(_rbexpr.slice(offset._rbexpr, length._rbexpr))
781
+ _from_rbexpr(_rbexpr.slice(offset._rbexpr, length._rbexpr))
786
782
  end
787
783
 
788
784
  # Append expressions.
@@ -816,7 +812,7 @@ module Polars
816
812
  # # └─────┴──────┘
817
813
  def append(other, upcast: true)
818
814
  other = Utils.expr_to_lit_or_expr(other)
819
- wrap_expr(_rbexpr.append(other._rbexpr, upcast))
815
+ _from_rbexpr(_rbexpr.append(other._rbexpr, upcast))
820
816
  end
821
817
 
822
818
  # Create a single chunk of memory for this Series.
@@ -841,7 +837,7 @@ module Polars
841
837
  # # │ 2 │
842
838
  # # └────────┘
843
839
  def rechunk
844
- wrap_expr(_rbexpr.rechunk)
840
+ _from_rbexpr(_rbexpr.rechunk)
845
841
  end
846
842
 
847
843
  # Drop null values.
@@ -868,7 +864,7 @@ module Polars
868
864
  # # │ NaN │
869
865
  # # └─────┘
870
866
  def drop_nulls
871
- wrap_expr(_rbexpr.drop_nulls)
867
+ _from_rbexpr(_rbexpr.drop_nulls)
872
868
  end
873
869
 
874
870
  # Drop floating point NaN values.
@@ -895,7 +891,7 @@ module Polars
895
891
  # # │ 4.0 │
896
892
  # # └──────┘
897
893
  def drop_nans
898
- wrap_expr(_rbexpr.drop_nans)
894
+ _from_rbexpr(_rbexpr.drop_nans)
899
895
  end
900
896
 
901
897
  # Get an array with the cumulative sum computed at every element.
@@ -930,7 +926,7 @@ module Polars
930
926
  # # │ 10 ┆ 4 │
931
927
  # # └─────┴───────────┘
932
928
  def cum_sum(reverse: false)
933
- wrap_expr(_rbexpr.cum_sum(reverse))
929
+ _from_rbexpr(_rbexpr.cum_sum(reverse))
934
930
  end
935
931
  alias_method :cumsum, :cum_sum
936
932
 
@@ -966,7 +962,7 @@ module Polars
966
962
  # # │ 24 ┆ 4 │
967
963
  # # └─────┴───────────┘
968
964
  def cum_prod(reverse: false)
969
- wrap_expr(_rbexpr.cum_prod(reverse))
965
+ _from_rbexpr(_rbexpr.cum_prod(reverse))
970
966
  end
971
967
  alias_method :cumprod, :cum_prod
972
968
 
@@ -998,7 +994,7 @@ module Polars
998
994
  # # │ 1 ┆ 4 │
999
995
  # # └─────┴───────────┘
1000
996
  def cum_min(reverse: false)
1001
- wrap_expr(_rbexpr.cum_min(reverse))
997
+ _from_rbexpr(_rbexpr.cum_min(reverse))
1002
998
  end
1003
999
  alias_method :cummin, :cum_min
1004
1000
 
@@ -1030,7 +1026,7 @@ module Polars
1030
1026
  # # │ 4 ┆ 4 │
1031
1027
  # # └─────┴───────────┘
1032
1028
  def cum_max(reverse: false)
1033
- wrap_expr(_rbexpr.cum_max(reverse))
1029
+ _from_rbexpr(_rbexpr.cum_max(reverse))
1034
1030
  end
1035
1031
  alias_method :cummax, :cum_max
1036
1032
 
@@ -1044,27 +1040,27 @@ module Polars
1044
1040
  # @return [Expr]
1045
1041
  #
1046
1042
  # @example
1047
- # df = Polars::DataFrame.new({"a" => [1, 2, 3, 4]})
1048
- # df.select(
1043
+ # df = Polars::DataFrame.new({"a" => ["x", "k", nil, "d"]})
1044
+ # df.with_columns(
1049
1045
  # [
1050
- # Polars.col("a").cum_count,
1051
- # Polars.col("a").cum_count(reverse: true).alias("a_reverse")
1046
+ # Polars.col("a").cum_count.alias("cum_count"),
1047
+ # Polars.col("a").cum_count(reverse: true).alias("cum_count_reverse")
1052
1048
  # ]
1053
1049
  # )
1054
1050
  # # =>
1055
- # # shape: (4, 2)
1056
- # # ┌─────┬───────────┐
1057
- # # │ a a_reverse
1058
- # # │ --- ┆ ---
1059
- # # │ u32 ┆ u32
1060
- # # ╞═════╪═══════════╡
1061
- # # │ 0 ┆ 3
1062
- # # │ 1 ┆ 2 │
1063
- # # │ 2 ┆ 1
1064
- # # │ 3 0
1065
- # # └─────┴───────────┘
1051
+ # # shape: (4, 3)
1052
+ # # ┌──────┬───────────┬───────────────────┐
1053
+ # # │ a cum_count ┆ cum_count_reverse
1054
+ # # │ --- --- ┆ ---
1055
+ # # │ str ┆ u32 ┆ u32
1056
+ # # ╞══════╪═══════════╪═══════════════════╡
1057
+ # # │ x 1 ┆ 3
1058
+ # # │ k ┆ 2 ┆ 2
1059
+ # # │ null ┆ 2 ┆ 1
1060
+ # # │ d ┆ 3 1
1061
+ # # └──────┴───────────┴───────────────────┘
1066
1062
  def cum_count(reverse: false)
1067
- wrap_expr(_rbexpr.cum_count(reverse))
1063
+ _from_rbexpr(_rbexpr.cum_count(reverse))
1068
1064
  end
1069
1065
  alias_method :cumcount, :cum_count
1070
1066
 
@@ -1090,7 +1086,7 @@ module Polars
1090
1086
  # # │ 1.0 │
1091
1087
  # # └─────┘
1092
1088
  def floor
1093
- wrap_expr(_rbexpr.floor)
1089
+ _from_rbexpr(_rbexpr.floor)
1094
1090
  end
1095
1091
 
1096
1092
  # Rounds up to the nearest integer value.
@@ -1115,7 +1111,7 @@ module Polars
1115
1111
  # # │ 2.0 │
1116
1112
  # # └─────┘
1117
1113
  def ceil
1118
- wrap_expr(_rbexpr.ceil)
1114
+ _from_rbexpr(_rbexpr.ceil)
1119
1115
  end
1120
1116
 
1121
1117
  # Round underlying floating point data by `decimals` digits.
@@ -1141,7 +1137,7 @@ module Polars
1141
1137
  # # │ 1.2 │
1142
1138
  # # └─────┘
1143
1139
  def round(decimals = 0)
1144
- wrap_expr(_rbexpr.round(decimals))
1140
+ _from_rbexpr(_rbexpr.round(decimals))
1145
1141
  end
1146
1142
 
1147
1143
  # Compute the dot/inner product between two Expressions.
@@ -1170,7 +1166,7 @@ module Polars
1170
1166
  # # └─────┘
1171
1167
  def dot(other)
1172
1168
  other = Utils.expr_to_lit_or_expr(other, str_to_lit: false)
1173
- wrap_expr(_rbexpr.dot(other._rbexpr))
1169
+ _from_rbexpr(_rbexpr.dot(other._rbexpr))
1174
1170
  end
1175
1171
 
1176
1172
  # Compute the most occurring value(s).
@@ -1198,7 +1194,7 @@ module Polars
1198
1194
  # # │ 1 ┆ 2 │
1199
1195
  # # └─────┴─────┘
1200
1196
  def mode
1201
- wrap_expr(_rbexpr.mode)
1197
+ _from_rbexpr(_rbexpr.mode)
1202
1198
  end
1203
1199
 
1204
1200
  # Cast between data types.
@@ -1237,7 +1233,7 @@ module Polars
1237
1233
  # # └─────┴─────┘
1238
1234
  def cast(dtype, strict: true)
1239
1235
  dtype = Utils.rb_type_to_dtype(dtype)
1240
- wrap_expr(_rbexpr.cast(dtype, strict))
1236
+ _from_rbexpr(_rbexpr.cast(dtype, strict))
1241
1237
  end
1242
1238
 
1243
1239
  # Sort this column. In projection/ selection context the whole column is sorted.
@@ -1312,7 +1308,7 @@ module Polars
1312
1308
  # # │ one ┆ [1, 2, 98] │
1313
1309
  # # └───────┴────────────┘
1314
1310
  def sort(reverse: false, nulls_last: false)
1315
- wrap_expr(_rbexpr.sort_with(reverse, nulls_last))
1311
+ _from_rbexpr(_rbexpr.sort_with(reverse, nulls_last))
1316
1312
  end
1317
1313
 
1318
1314
  # Return the `k` largest elements.
@@ -1351,7 +1347,7 @@ module Polars
1351
1347
  # # └───────┴──────────┘
1352
1348
  def top_k(k: 5)
1353
1349
  k = Utils.parse_as_expression(k)
1354
- wrap_expr(_rbexpr.top_k(k))
1350
+ _from_rbexpr(_rbexpr.top_k(k))
1355
1351
  end
1356
1352
 
1357
1353
  # Return the `k` smallest elements.
@@ -1390,7 +1386,7 @@ module Polars
1390
1386
  # # └───────┴──────────┘
1391
1387
  def bottom_k(k: 5)
1392
1388
  k = Utils.parse_as_expression(k)
1393
- wrap_expr(_rbexpr.bottom_k(k))
1389
+ _from_rbexpr(_rbexpr.bottom_k(k))
1394
1390
  end
1395
1391
 
1396
1392
  # Get the index values that would sort this column.
@@ -1421,7 +1417,7 @@ module Polars
1421
1417
  # # │ 2 │
1422
1418
  # # └─────┘
1423
1419
  def arg_sort(reverse: false, nulls_last: false)
1424
- wrap_expr(_rbexpr.arg_sort(reverse, nulls_last))
1420
+ _from_rbexpr(_rbexpr.arg_sort(reverse, nulls_last))
1425
1421
  end
1426
1422
 
1427
1423
  # Get the index of the maximal value.
@@ -1445,7 +1441,7 @@ module Polars
1445
1441
  # # │ 2 │
1446
1442
  # # └─────┘
1447
1443
  def arg_max
1448
- wrap_expr(_rbexpr.arg_max)
1444
+ _from_rbexpr(_rbexpr.arg_max)
1449
1445
  end
1450
1446
 
1451
1447
  # Get the index of the minimal value.
@@ -1469,7 +1465,7 @@ module Polars
1469
1465
  # # │ 1 │
1470
1466
  # # └─────┘
1471
1467
  def arg_min
1472
- wrap_expr(_rbexpr.arg_min)
1468
+ _from_rbexpr(_rbexpr.arg_min)
1473
1469
  end
1474
1470
 
1475
1471
  # Find indices where elements should be inserted to maintain order.
@@ -1503,7 +1499,7 @@ module Polars
1503
1499
  # # └──────┴───────┴─────┘
1504
1500
  def search_sorted(element, side: "any")
1505
1501
  element = Utils.expr_to_lit_or_expr(element, str_to_lit: false)
1506
- wrap_expr(_rbexpr.search_sorted(element._rbexpr, side))
1502
+ _from_rbexpr(_rbexpr.search_sorted(element._rbexpr, side))
1507
1503
  end
1508
1504
 
1509
1505
  # Sort this column by the ordering of another column, or multiple other columns.
@@ -1548,16 +1544,14 @@ module Polars
1548
1544
  # # │ one │
1549
1545
  # # │ two │
1550
1546
  # # └───────┘
1551
- def sort_by(by, reverse: false)
1552
- if !by.is_a?(::Array)
1553
- by = [by]
1554
- end
1547
+ def sort_by(by, *more_by, reverse: false, nulls_last: false, multithreaded: true, maintain_order: false)
1548
+ by = Utils.parse_as_list_of_expressions(by, *more_by)
1555
1549
  if !reverse.is_a?(::Array)
1556
1550
  reverse = [reverse]
1551
+ elsif by.length != reverse.length
1552
+ raise ArgumentError, "the length of `reverse` (#{reverse.length}) does not match the length of `by` (#{by.length})"
1557
1553
  end
1558
- by = Utils.selection_to_rbexpr_list(by)
1559
-
1560
- wrap_expr(_rbexpr.sort_by(by, reverse))
1554
+ _from_rbexpr(_rbexpr.sort_by(by, reverse, nulls_last, multithreaded, maintain_order))
1561
1555
  end
1562
1556
 
1563
1557
  # Take values by index.
@@ -1598,7 +1592,7 @@ module Polars
1598
1592
  else
1599
1593
  indices_lit = Utils.expr_to_lit_or_expr(indices, str_to_lit: false)
1600
1594
  end
1601
- wrap_expr(_rbexpr.gather(indices_lit._rbexpr))
1595
+ _from_rbexpr(_rbexpr.gather(indices_lit._rbexpr))
1602
1596
  end
1603
1597
  alias_method :take, :gather
1604
1598
 
@@ -1631,7 +1625,7 @@ module Polars
1631
1625
  fill_value = Utils.parse_as_expression(fill_value, str_as_lit: true)
1632
1626
  end
1633
1627
  n = Utils.parse_as_expression(n)
1634
- wrap_expr(_rbexpr.shift(n, fill_value))
1628
+ _from_rbexpr(_rbexpr.shift(n, fill_value))
1635
1629
  end
1636
1630
 
1637
1631
  # Shift the values by a given period and fill the resulting null values.
@@ -1734,9 +1728,9 @@ module Polars
1734
1728
 
1735
1729
  if !value.nil?
1736
1730
  value = Utils.expr_to_lit_or_expr(value, str_to_lit: true)
1737
- wrap_expr(_rbexpr.fill_null(value._rbexpr))
1731
+ _from_rbexpr(_rbexpr.fill_null(value._rbexpr))
1738
1732
  else
1739
- wrap_expr(_rbexpr.fill_null_with_strategy(strategy, limit))
1733
+ _from_rbexpr(_rbexpr.fill_null_with_strategy(strategy, limit))
1740
1734
  end
1741
1735
  end
1742
1736
 
@@ -1765,7 +1759,7 @@ module Polars
1765
1759
  # # └──────┴──────┘
1766
1760
  def fill_nan(fill_value)
1767
1761
  fill_value = Utils.expr_to_lit_or_expr(fill_value, str_to_lit: true)
1768
- wrap_expr(_rbexpr.fill_nan(fill_value._rbexpr))
1762
+ _from_rbexpr(_rbexpr.fill_nan(fill_value._rbexpr))
1769
1763
  end
1770
1764
 
1771
1765
  # Fill missing values with the latest seen values.
@@ -1795,7 +1789,7 @@ module Polars
1795
1789
  # # │ 2 ┆ 6 │
1796
1790
  # # └─────┴─────┘
1797
1791
  def forward_fill(limit: nil)
1798
- wrap_expr(_rbexpr.forward_fill(limit))
1792
+ _from_rbexpr(_rbexpr.forward_fill(limit))
1799
1793
  end
1800
1794
 
1801
1795
  # Fill missing values with the next to be seen values.
@@ -1825,14 +1819,14 @@ module Polars
1825
1819
  # # │ null ┆ 6 │
1826
1820
  # # └──────┴─────┘
1827
1821
  def backward_fill(limit: nil)
1828
- wrap_expr(_rbexpr.backward_fill(limit))
1822
+ _from_rbexpr(_rbexpr.backward_fill(limit))
1829
1823
  end
1830
1824
 
1831
1825
  # Reverse the selection.
1832
1826
  #
1833
1827
  # @return [Expr]
1834
1828
  def reverse
1835
- wrap_expr(_rbexpr.reverse)
1829
+ _from_rbexpr(_rbexpr.reverse)
1836
1830
  end
1837
1831
 
1838
1832
  # Get standard deviation.
@@ -1855,7 +1849,7 @@ module Polars
1855
1849
  # # │ 1.0 │
1856
1850
  # # └─────┘
1857
1851
  def std(ddof: 1)
1858
- wrap_expr(_rbexpr.std(ddof))
1852
+ _from_rbexpr(_rbexpr.std(ddof))
1859
1853
  end
1860
1854
 
1861
1855
  # Get variance.
@@ -1878,7 +1872,7 @@ module Polars
1878
1872
  # # │ 1.0 │
1879
1873
  # # └─────┘
1880
1874
  def var(ddof: 1)
1881
- wrap_expr(_rbexpr.var(ddof))
1875
+ _from_rbexpr(_rbexpr.var(ddof))
1882
1876
  end
1883
1877
 
1884
1878
  # Get maximum value.
@@ -1898,7 +1892,7 @@ module Polars
1898
1892
  # # │ 1.0 │
1899
1893
  # # └─────┘
1900
1894
  def max
1901
- wrap_expr(_rbexpr.max)
1895
+ _from_rbexpr(_rbexpr.max)
1902
1896
  end
1903
1897
 
1904
1898
  # Get minimum value.
@@ -1918,7 +1912,7 @@ module Polars
1918
1912
  # # │ -1.0 │
1919
1913
  # # └──────┘
1920
1914
  def min
1921
- wrap_expr(_rbexpr.min)
1915
+ _from_rbexpr(_rbexpr.min)
1922
1916
  end
1923
1917
 
1924
1918
  # Get maximum value, but propagate/poison encountered NaN values.
@@ -1938,7 +1932,7 @@ module Polars
1938
1932
  # # │ NaN │
1939
1933
  # # └─────┘
1940
1934
  def nan_max
1941
- wrap_expr(_rbexpr.nan_max)
1935
+ _from_rbexpr(_rbexpr.nan_max)
1942
1936
  end
1943
1937
 
1944
1938
  # Get minimum value, but propagate/poison encountered NaN values.
@@ -1958,7 +1952,7 @@ module Polars
1958
1952
  # # │ NaN │
1959
1953
  # # └─────┘
1960
1954
  def nan_min
1961
- wrap_expr(_rbexpr.nan_min)
1955
+ _from_rbexpr(_rbexpr.nan_min)
1962
1956
  end
1963
1957
 
1964
1958
  # Get sum value.
@@ -1982,7 +1976,7 @@ module Polars
1982
1976
  # # │ 0 │
1983
1977
  # # └─────┘
1984
1978
  def sum
1985
- wrap_expr(_rbexpr.sum)
1979
+ _from_rbexpr(_rbexpr.sum)
1986
1980
  end
1987
1981
 
1988
1982
  # Get mean value.
@@ -2002,7 +1996,7 @@ module Polars
2002
1996
  # # │ 0.0 │
2003
1997
  # # └─────┘
2004
1998
  def mean
2005
- wrap_expr(_rbexpr.mean)
1999
+ _from_rbexpr(_rbexpr.mean)
2006
2000
  end
2007
2001
 
2008
2002
  # Get median value using linear interpolation.
@@ -2022,7 +2016,7 @@ module Polars
2022
2016
  # # │ 0.0 │
2023
2017
  # # └─────┘
2024
2018
  def median
2025
- wrap_expr(_rbexpr.median)
2019
+ _from_rbexpr(_rbexpr.median)
2026
2020
  end
2027
2021
 
2028
2022
  # Compute the product of an expression.
@@ -2042,7 +2036,7 @@ module Polars
2042
2036
  # # │ 6 │
2043
2037
  # # └─────┘
2044
2038
  def product
2045
- wrap_expr(_rbexpr.product)
2039
+ _from_rbexpr(_rbexpr.product)
2046
2040
  end
2047
2041
 
2048
2042
  # Count unique values.
@@ -2062,7 +2056,7 @@ module Polars
2062
2056
  # # │ 2 │
2063
2057
  # # └─────┘
2064
2058
  def n_unique
2065
- wrap_expr(_rbexpr.n_unique)
2059
+ _from_rbexpr(_rbexpr.n_unique)
2066
2060
  end
2067
2061
 
2068
2062
  # Approx count unique values.
@@ -2073,7 +2067,7 @@ module Polars
2073
2067
  #
2074
2068
  # @example
2075
2069
  # df = Polars::DataFrame.new({"a" => [1, 1, 2]})
2076
- # df.select(Polars.col("a").approx_unique)
2070
+ # df.select(Polars.col("a").approx_n_unique)
2077
2071
  # # =>
2078
2072
  # # shape: (1, 1)
2079
2073
  # # ┌─────┐
@@ -2083,9 +2077,10 @@ module Polars
2083
2077
  # # ╞═════╡
2084
2078
  # # │ 2 │
2085
2079
  # # └─────┘
2086
- def approx_unique
2087
- wrap_expr(_rbexpr.approx_n_unique)
2080
+ def approx_n_unique
2081
+ _from_rbexpr(_rbexpr.approx_n_unique)
2088
2082
  end
2083
+ alias_method :approx_unique, :approx_n_unique
2089
2084
 
2090
2085
  # Count null values.
2091
2086
  #
@@ -2109,7 +2104,7 @@ module Polars
2109
2104
  # # │ 2 ┆ 0 │
2110
2105
  # # └─────┴─────┘
2111
2106
  def null_count
2112
- wrap_expr(_rbexpr.null_count)
2107
+ _from_rbexpr(_rbexpr.null_count)
2113
2108
  end
2114
2109
 
2115
2110
  # Get index of first unique value.
@@ -2149,7 +2144,7 @@ module Polars
2149
2144
  # # │ 1 │
2150
2145
  # # └─────┘
2151
2146
  def arg_unique
2152
- wrap_expr(_rbexpr.arg_unique)
2147
+ _from_rbexpr(_rbexpr.arg_unique)
2153
2148
  end
2154
2149
 
2155
2150
  # Get unique values of this expression.
@@ -2174,9 +2169,9 @@ module Polars
2174
2169
  # # └─────┘
2175
2170
  def unique(maintain_order: false)
2176
2171
  if maintain_order
2177
- wrap_expr(_rbexpr.unique_stable)
2172
+ _from_rbexpr(_rbexpr.unique_stable)
2178
2173
  else
2179
- wrap_expr(_rbexpr.unique)
2174
+ _from_rbexpr(_rbexpr.unique)
2180
2175
  end
2181
2176
  end
2182
2177
 
@@ -2197,7 +2192,7 @@ module Polars
2197
2192
  # # │ 1 │
2198
2193
  # # └─────┘
2199
2194
  def first
2200
- wrap_expr(_rbexpr.first)
2195
+ _from_rbexpr(_rbexpr.first)
2201
2196
  end
2202
2197
 
2203
2198
  # Get the last value.
@@ -2217,7 +2212,7 @@ module Polars
2217
2212
  # # │ 2 │
2218
2213
  # # └─────┘
2219
2214
  def last
2220
- wrap_expr(_rbexpr.last)
2215
+ _from_rbexpr(_rbexpr.last)
2221
2216
  end
2222
2217
 
2223
2218
  # Apply window function over a subgroup.
@@ -2281,7 +2276,7 @@ module Polars
2281
2276
  # # └────────┘
2282
2277
  def over(expr)
2283
2278
  rbexprs = Utils.selection_to_rbexpr_list(expr)
2284
- wrap_expr(_rbexpr.over(rbexprs))
2279
+ _from_rbexpr(_rbexpr.over(rbexprs))
2285
2280
  end
2286
2281
 
2287
2282
  # Get mask of unique values.
@@ -2303,7 +2298,7 @@ module Polars
2303
2298
  # # │ true │
2304
2299
  # # └───────┘
2305
2300
  def is_unique
2306
- wrap_expr(_rbexpr.is_unique)
2301
+ _from_rbexpr(_rbexpr.is_unique)
2307
2302
  end
2308
2303
 
2309
2304
  # Get a mask of the first unique value.
@@ -2331,7 +2326,7 @@ module Polars
2331
2326
  # # │ 5 ┆ true │
2332
2327
  # # └─────┴──────────┘
2333
2328
  def is_first_distinct
2334
- wrap_expr(_rbexpr.is_first_distinct)
2329
+ _from_rbexpr(_rbexpr.is_first_distinct)
2335
2330
  end
2336
2331
  alias_method :is_first, :is_first_distinct
2337
2332
 
@@ -2354,7 +2349,7 @@ module Polars
2354
2349
  # # │ false │
2355
2350
  # # └───────┘
2356
2351
  def is_duplicated
2357
- wrap_expr(_rbexpr.is_duplicated)
2352
+ _from_rbexpr(_rbexpr.is_duplicated)
2358
2353
  end
2359
2354
 
2360
2355
  # Get a boolean mask of the local maximum peaks.
@@ -2378,7 +2373,7 @@ module Polars
2378
2373
  # # │ true │
2379
2374
  # # └───────┘
2380
2375
  def peak_max
2381
- wrap_expr(_rbexpr.peak_max)
2376
+ _from_rbexpr(_rbexpr.peak_max)
2382
2377
  end
2383
2378
 
2384
2379
  # Get a boolean mask of the local minimum peaks.
@@ -2402,7 +2397,7 @@ module Polars
2402
2397
  # # │ false │
2403
2398
  # # └───────┘
2404
2399
  def peak_min
2405
- wrap_expr(_rbexpr.peak_min)
2400
+ _from_rbexpr(_rbexpr.peak_min)
2406
2401
  end
2407
2402
 
2408
2403
  # Get quantile value.
@@ -2476,7 +2471,7 @@ module Polars
2476
2471
  # # └─────┘
2477
2472
  def quantile(quantile, interpolation: "nearest")
2478
2473
  quantile = Utils.expr_to_lit_or_expr(quantile, str_to_lit: false)
2479
- wrap_expr(_rbexpr.quantile(quantile._rbexpr, interpolation))
2474
+ _from_rbexpr(_rbexpr.quantile(quantile._rbexpr, interpolation))
2480
2475
  end
2481
2476
 
2482
2477
  # Bin continuous values into discrete categories.
@@ -2532,7 +2527,7 @@ module Polars
2532
2527
  # # │ 2 ┆ inf ┆ (1, inf] │
2533
2528
  # # └─────┴──────┴────────────┘
2534
2529
  def cut(breaks, labels: nil, left_closed: false, include_breaks: false)
2535
- wrap_expr(_rbexpr.cut(breaks, labels, left_closed, include_breaks))
2530
+ _from_rbexpr(_rbexpr.cut(breaks, labels, left_closed, include_breaks))
2536
2531
  end
2537
2532
 
2538
2533
  # Bin continuous values into discrete categories based on their quantiles.
@@ -2623,7 +2618,7 @@ module Polars
2623
2618
  )
2624
2619
  end
2625
2620
 
2626
- wrap_expr(rbexpr)
2621
+ _from_rbexpr(rbexpr)
2627
2622
  end
2628
2623
 
2629
2624
  # Get the lengths of runs of identical values.
@@ -2648,7 +2643,7 @@ module Polars
2648
2643
  # # │ 2 ┆ 3 │
2649
2644
  # # └─────────┴────────┘
2650
2645
  def rle
2651
- wrap_expr(_rbexpr.rle)
2646
+ _from_rbexpr(_rbexpr.rle)
2652
2647
  end
2653
2648
 
2654
2649
  # Map values to run IDs.
@@ -2676,7 +2671,7 @@ module Polars
2676
2671
  # # │ 1 ┆ y ┆ 2 ┆ 3 │
2677
2672
  # # └─────┴──────┴─────┴──────┘
2678
2673
  def rle_id
2679
- wrap_expr(_rbexpr.rle_id)
2674
+ _from_rbexpr(_rbexpr.rle_id)
2680
2675
  end
2681
2676
 
2682
2677
  # Filter a single column.
@@ -2715,7 +2710,7 @@ module Polars
2715
2710
  # # │ g2 ┆ 0 ┆ 3 │
2716
2711
  # # └───────────┴─────┴─────┘
2717
2712
  def filter(predicate)
2718
- wrap_expr(_rbexpr.filter(predicate._rbexpr))
2713
+ _from_rbexpr(_rbexpr.filter(predicate._rbexpr))
2719
2714
  end
2720
2715
 
2721
2716
  # Filter a single column.
@@ -2793,7 +2788,7 @@ module Polars
2793
2788
  # if !return_dtype.nil?
2794
2789
  # return_dtype = Utils.rb_type_to_dtype(return_dtype)
2795
2790
  # end
2796
- # wrap_expr(_rbexpr.map(f, return_dtype, agg_list))
2791
+ # _from_rbexpr(_rbexpr.map(f, return_dtype, agg_list))
2797
2792
  # end
2798
2793
 
2799
2794
  # Apply a custom/user-defined function (UDF) in a GroupBy or Projection context.
@@ -2904,7 +2899,7 @@ module Polars
2904
2899
  # # │ b ┆ [2, 3, 4] │
2905
2900
  # # └───────┴───────────┘
2906
2901
  def flatten
2907
- wrap_expr(_rbexpr.explode)
2902
+ _from_rbexpr(_rbexpr.explode)
2908
2903
  end
2909
2904
 
2910
2905
  # Explode a list or utf8 Series.
@@ -2931,7 +2926,7 @@ module Polars
2931
2926
  # # │ 6 │
2932
2927
  # # └─────┘
2933
2928
  def explode
2934
- wrap_expr(_rbexpr.explode)
2929
+ _from_rbexpr(_rbexpr.explode)
2935
2930
  end
2936
2931
 
2937
2932
  # Take every nth value in the Series and return as a new Series.
@@ -2953,7 +2948,7 @@ module Polars
2953
2948
  # # │ 7 │
2954
2949
  # # └─────┘
2955
2950
  def gather_every(n, offset = 0)
2956
- wrap_expr(_rbexpr.gather_every(n, offset))
2951
+ _from_rbexpr(_rbexpr.gather_every(n, offset))
2957
2952
  end
2958
2953
  alias_method :take_every, :gather_every
2959
2954
 
@@ -2979,7 +2974,7 @@ module Polars
2979
2974
  # # │ 3 │
2980
2975
  # # └─────┘
2981
2976
  def head(n = 10)
2982
- wrap_expr(_rbexpr.head(n))
2977
+ _from_rbexpr(_rbexpr.head(n))
2983
2978
  end
2984
2979
 
2985
2980
  # Get the last `n` rows.
@@ -3004,7 +2999,7 @@ module Polars
3004
2999
  # # │ 7 │
3005
3000
  # # └─────┘
3006
3001
  def tail(n = 10)
3007
- wrap_expr(_rbexpr.tail(n))
3002
+ _from_rbexpr(_rbexpr.tail(n))
3008
3003
  end
3009
3004
 
3010
3005
  # Get the first `n` rows.
@@ -3019,28 +3014,552 @@ module Polars
3019
3014
  head(n)
3020
3015
  end
3021
3016
 
3022
- # Raise expression to the power of exponent.
3017
+ # Method equivalent of equality operator `expr == other`.
3018
+ #
3019
+ # @param other [Object]
3020
+ # A literal or expression value to compare with.
3021
+ #
3022
+ # @return [Expr]
3023
+ # @example
3024
+ # df = Polars::DataFrame.new(
3025
+ # {
3026
+ # "x" => [1.0, 2.0, Float::NAN, 4.0],
3027
+ # "y" => [2.0, 2.0, Float::NAN, 4.0]
3028
+ # }
3029
+ # )
3030
+ # df.with_columns(
3031
+ # Polars.col("x").eq(Polars.col("y")).alias("x == y")
3032
+ # )
3033
+ # # =>
3034
+ # # shape: (4, 3)
3035
+ # # ┌─────┬─────┬────────┐
3036
+ # # │ x ┆ y ┆ x == y │
3037
+ # # │ --- ┆ --- ┆ --- │
3038
+ # # │ f64 ┆ f64 ┆ bool │
3039
+ # # ╞═════╪═════╪════════╡
3040
+ # # │ 1.0 ┆ 2.0 ┆ false │
3041
+ # # │ 2.0 ┆ 2.0 ┆ true │
3042
+ # # │ NaN ┆ NaN ┆ true │
3043
+ # # │ 4.0 ┆ 4.0 ┆ true │
3044
+ # # └─────┴─────┴────────┘
3045
+ def eq(other)
3046
+ self == other
3047
+ end
3048
+
3049
+ # Method equivalent of equality operator `expr == other` where `None == None`.
3050
+ #
3051
+ # This differs from default `eq` where null values are propagated.
3052
+ #
3053
+ # @param other [Object]
3054
+ # A literal or expression value to compare with.
3023
3055
  #
3024
3056
  # @return [Expr]
3025
3057
  #
3026
3058
  # @example
3027
- # df = Polars::DataFrame.new({"foo" => [1, 2, 3, 4]})
3028
- # df.select(Polars.col("foo").pow(3))
3059
+ # df = Polars::DataFrame.new(
3060
+ # data={
3061
+ # "x" => [1.0, 2.0, Float::NAN, 4.0, nil, nil],
3062
+ # "y" => [2.0, 2.0, Float::NAN, 4.0, 5.0, nil]
3063
+ # }
3064
+ # )
3065
+ # df.with_columns(
3066
+ # Polars.col("x").eq(Polars.col("y")).alias("x eq y"),
3067
+ # Polars.col("x").eq_missing(Polars.col("y")).alias("x eq_missing y")
3068
+ # )
3069
+ # # =>
3070
+ # # shape: (6, 4)
3071
+ # # ┌──────┬──────┬────────┬────────────────┐
3072
+ # # │ x ┆ y ┆ x eq y ┆ x eq_missing y │
3073
+ # # │ --- ┆ --- ┆ --- ┆ --- │
3074
+ # # │ f64 ┆ f64 ┆ bool ┆ bool │
3075
+ # # ╞══════╪══════╪════════╪════════════════╡
3076
+ # # │ 1.0 ┆ 2.0 ┆ false ┆ false │
3077
+ # # │ 2.0 ┆ 2.0 ┆ true ┆ true │
3078
+ # # │ NaN ┆ NaN ┆ true ┆ true │
3079
+ # # │ 4.0 ┆ 4.0 ┆ true ┆ true │
3080
+ # # │ null ┆ 5.0 ┆ null ┆ false │
3081
+ # # │ null ┆ null ┆ null ┆ true │
3082
+ # # └──────┴──────┴────────┴────────────────┘
3083
+ def eq_missing(other)
3084
+ other = Utils.parse_as_expression(other, str_as_lit: true)
3085
+ _from_rbexpr(_rbexpr.eq_missing(other))
3086
+ end
3087
+
3088
+ # Method equivalent of "greater than or equal" operator `expr >= other`.
3089
+ #
3090
+ # @param other [Object]
3091
+ # A literal or expression value to compare with.
3092
+ #
3093
+ # @return [Expr]
3094
+ #
3095
+ # @example
3096
+ # df = Polars::DataFrame.new(
3097
+ # {
3098
+ # "x" => [5.0, 4.0, Float::NAN, 2.0],
3099
+ # "y" => [5.0, 3.0, Float::NAN, 1.0]
3100
+ # }
3101
+ # )
3102
+ # df.with_columns(
3103
+ # Polars.col("x").ge(Polars.col("y")).alias("x >= y")
3104
+ # )
3105
+ # # =>
3106
+ # # shape: (4, 3)
3107
+ # # ┌─────┬─────┬────────┐
3108
+ # # │ x ┆ y ┆ x >= y │
3109
+ # # │ --- ┆ --- ┆ --- │
3110
+ # # │ f64 ┆ f64 ┆ bool │
3111
+ # # ╞═════╪═════╪════════╡
3112
+ # # │ 5.0 ┆ 5.0 ┆ true │
3113
+ # # │ 4.0 ┆ 3.0 ┆ true │
3114
+ # # │ NaN ┆ NaN ┆ true │
3115
+ # # │ 2.0 ┆ 1.0 ┆ true │
3116
+ # # └─────┴─────┴────────┘
3117
+ def ge(other)
3118
+ self >= other
3119
+ end
3120
+
3121
+ # Method equivalent of "greater than" operator `expr > other`.
3122
+ #
3123
+ # @param other [Object]
3124
+ # A literal or expression value to compare with.
3125
+ #
3126
+ # @return [Expr]
3127
+ #
3128
+ # @example
3129
+ # df = Polars::DataFrame.new(
3130
+ # {
3131
+ # "x" => [5.0, 4.0, Float::NAN, 2.0],
3132
+ # "y" => [5.0, 3.0, Float::NAN, 1.0]
3133
+ # }
3134
+ # )
3135
+ # df.with_columns(
3136
+ # Polars.col("x").gt(Polars.col("y")).alias("x > y")
3137
+ # )
3138
+ # # =>
3139
+ # # shape: (4, 3)
3140
+ # # ┌─────┬─────┬───────┐
3141
+ # # │ x ┆ y ┆ x > y │
3142
+ # # │ --- ┆ --- ┆ --- │
3143
+ # # │ f64 ┆ f64 ┆ bool │
3144
+ # # ╞═════╪═════╪═══════╡
3145
+ # # │ 5.0 ┆ 5.0 ┆ false │
3146
+ # # │ 4.0 ┆ 3.0 ┆ true │
3147
+ # # │ NaN ┆ NaN ┆ false │
3148
+ # # │ 2.0 ┆ 1.0 ┆ true │
3149
+ # # └─────┴─────┴───────┘
3150
+ def gt(other)
3151
+ self > other
3152
+ end
3153
+
3154
+ # Method equivalent of "less than or equal" operator `expr <= other`.
3155
+ #
3156
+ # @param other [Object]
3157
+ # A literal or expression value to compare with.
3158
+ #
3159
+ # @return [Expr]
3160
+ #
3161
+ # @example
3162
+ # df = Polars::DataFrame.new(
3163
+ # {
3164
+ # "x" => [5.0, 4.0, Float::NAN, 0.5],
3165
+ # "y" => [5.0, 3.5, Float::NAN, 2.0]
3166
+ # }
3167
+ # )
3168
+ # df.with_columns(
3169
+ # Polars.col("x").le(Polars.col("y")).alias("x <= y")
3170
+ # )
3171
+ # # =>
3172
+ # # shape: (4, 3)
3173
+ # # ┌─────┬─────┬────────┐
3174
+ # # │ x ┆ y ┆ x <= y │
3175
+ # # │ --- ┆ --- ┆ --- │
3176
+ # # │ f64 ┆ f64 ┆ bool │
3177
+ # # ╞═════╪═════╪════════╡
3178
+ # # │ 5.0 ┆ 5.0 ┆ true │
3179
+ # # │ 4.0 ┆ 3.5 ┆ false │
3180
+ # # │ NaN ┆ NaN ┆ true │
3181
+ # # │ 0.5 ┆ 2.0 ┆ true │
3182
+ # # └─────┴─────┴────────┘
3183
+ def le(other)
3184
+ self <= other
3185
+ end
3186
+
3187
+ # Method equivalent of "less than" operator `expr < other`.
3188
+ #
3189
+ # @param other [Object]
3190
+ # A literal or expression value to compare with.
3191
+ #
3192
+ # @return [Expr]
3193
+ #
3194
+ # @example
3195
+ # df = Polars::DataFrame.new(
3196
+ # {
3197
+ # "x" => [1.0, 2.0, Float::NAN, 3.0],
3198
+ # "y" => [2.0, 2.0, Float::NAN, 4.0]
3199
+ # }
3200
+ # )
3201
+ # df.with_columns(
3202
+ # Polars.col("x").lt(Polars.col("y")).alias("x < y"),
3203
+ # )
3204
+ # # =>
3205
+ # # shape: (4, 3)
3206
+ # # ┌─────┬─────┬───────┐
3207
+ # # │ x ┆ y ┆ x < y │
3208
+ # # │ --- ┆ --- ┆ --- │
3209
+ # # │ f64 ┆ f64 ┆ bool │
3210
+ # # ╞═════╪═════╪═══════╡
3211
+ # # │ 1.0 ┆ 2.0 ┆ true │
3212
+ # # │ 2.0 ┆ 2.0 ┆ false │
3213
+ # # │ NaN ┆ NaN ┆ false │
3214
+ # # │ 3.0 ┆ 4.0 ┆ true │
3215
+ # # └─────┴─────┴───────┘
3216
+ def lt(other)
3217
+ self < other
3218
+ end
3219
+
3220
+ # Method equivalent of inequality operator `expr != other`.
3221
+ #
3222
+ # @param other [Object]
3223
+ # A literal or expression value to compare with.
3224
+ #
3225
+ # @return [Expr]
3226
+ #
3227
+ # @example
3228
+ # df = Polars::DataFrame.new(
3229
+ # {
3230
+ # "x" => [1.0, 2.0, Float::NAN, 4.0],
3231
+ # "y" => [2.0, 2.0, Float::NAN, 4.0]
3232
+ # }
3233
+ # )
3234
+ # df.with_columns(
3235
+ # Polars.col("x").ne(Polars.col("y")).alias("x != y"),
3236
+ # )
3237
+ # # =>
3238
+ # # shape: (4, 3)
3239
+ # # ┌─────┬─────┬────────┐
3240
+ # # │ x ┆ y ┆ x != y │
3241
+ # # │ --- ┆ --- ┆ --- │
3242
+ # # │ f64 ┆ f64 ┆ bool │
3243
+ # # ╞═════╪═════╪════════╡
3244
+ # # │ 1.0 ┆ 2.0 ┆ true │
3245
+ # # │ 2.0 ┆ 2.0 ┆ false │
3246
+ # # │ NaN ┆ NaN ┆ false │
3247
+ # # │ 4.0 ┆ 4.0 ┆ false │
3248
+ # # └─────┴─────┴────────┘
3249
+ def ne(other)
3250
+ self != other
3251
+ end
3252
+
3253
+ # Method equivalent of equality operator `expr != other` where `None == None`.
3254
+ #
3255
+ # This differs from default `ne` where null values are propagated.
3256
+ #
3257
+ # @param other [Object]
3258
+ # A literal or expression value to compare with.
3259
+ #
3260
+ # @return [Expr]
3261
+ #
3262
+ # @example
3263
+ # df = Polars::DataFrame.new(
3264
+ # {
3265
+ # "x" => [1.0, 2.0, Float::NAN, 4.0, nil, nil],
3266
+ # "y" => [2.0, 2.0, Float::NAN, 4.0, 5.0, nil]
3267
+ # }
3268
+ # )
3269
+ # df.with_columns(
3270
+ # Polars.col("x").ne(Polars.col("y")).alias("x ne y"),
3271
+ # Polars.col("x").ne_missing(Polars.col("y")).alias("x ne_missing y")
3272
+ # )
3273
+ # # =>
3274
+ # # shape: (6, 4)
3275
+ # # ┌──────┬──────┬────────┬────────────────┐
3276
+ # # │ x ┆ y ┆ x ne y ┆ x ne_missing y │
3277
+ # # │ --- ┆ --- ┆ --- ┆ --- │
3278
+ # # │ f64 ┆ f64 ┆ bool ┆ bool │
3279
+ # # ╞══════╪══════╪════════╪════════════════╡
3280
+ # # │ 1.0 ┆ 2.0 ┆ true ┆ true │
3281
+ # # │ 2.0 ┆ 2.0 ┆ false ┆ false │
3282
+ # # │ NaN ┆ NaN ┆ false ┆ false │
3283
+ # # │ 4.0 ┆ 4.0 ┆ false ┆ false │
3284
+ # # │ null ┆ 5.0 ┆ null ┆ true │
3285
+ # # │ null ┆ null ┆ null ┆ false │
3286
+ # # └──────┴──────┴────────┴────────────────┘
3287
+ def ne_missing(other)
3288
+ other = Utils.parse_as_expression(other, str_as_lit: true)
3289
+ _from_rbexpr(_rbexpr.neq_missing(other))
3290
+ end
3291
+
3292
+ # Method equivalent of addition operator `expr + other`.
3293
+ #
3294
+ # @param other [Object]
3295
+ # numeric or string value; accepts expression input.
3296
+ #
3297
+ # @return [Expr]
3298
+ #
3299
+ # @example
3300
+ # df = Polars::DataFrame.new({"x" => [1, 2, 3, 4, 5]})
3301
+ # df.with_columns(
3302
+ # Polars.col("x").add(2).alias("x+int"),
3303
+ # Polars.col("x").add(Polars.col("x").cum_prod).alias("x+expr")
3304
+ # )
3305
+ # # =>
3306
+ # # shape: (5, 3)
3307
+ # # ┌─────┬───────┬────────┐
3308
+ # # │ x ┆ x+int ┆ x+expr │
3309
+ # # │ --- ┆ --- ┆ --- │
3310
+ # # │ i64 ┆ i64 ┆ i64 │
3311
+ # # ╞═════╪═══════╪════════╡
3312
+ # # │ 1 ┆ 3 ┆ 2 │
3313
+ # # │ 2 ┆ 4 ┆ 4 │
3314
+ # # │ 3 ┆ 5 ┆ 9 │
3315
+ # # │ 4 ┆ 6 ┆ 28 │
3316
+ # # │ 5 ┆ 7 ┆ 125 │
3317
+ # # └─────┴───────┴────────┘
3318
+ #
3319
+ # @example
3320
+ # df = Polars::DataFrame.new(
3321
+ # {"x" => ["a", "d", "g"], "y": ["b", "e", "h"], "z": ["c", "f", "i"]}
3322
+ # )
3323
+ # df.with_columns(Polars.col("x").add(Polars.col("y")).add(Polars.col("z")).alias("xyz"))
3324
+ # # =>
3325
+ # # shape: (3, 4)
3326
+ # # ┌─────┬─────┬─────┬─────┐
3327
+ # # │ x ┆ y ┆ z ┆ xyz │
3328
+ # # │ --- ┆ --- ┆ --- ┆ --- │
3329
+ # # │ str ┆ str ┆ str ┆ str │
3330
+ # # ╞═════╪═════╪═════╪═════╡
3331
+ # # │ a ┆ b ┆ c ┆ abc │
3332
+ # # │ d ┆ e ┆ f ┆ def │
3333
+ # # │ g ┆ h ┆ i ┆ ghi │
3334
+ # # └─────┴─────┴─────┴─────┘
3335
+ def add(other)
3336
+ self + other
3337
+ end
3338
+
3339
+ # Method equivalent of integer division operator `expr // other`.
3340
+ #
3341
+ # @param other [Object]
3342
+ # Numeric literal or expression value.
3343
+ #
3344
+ # @return [Expr]
3345
+ #
3346
+ # @example
3347
+ # df = Polars::DataFrame.new({"x" => [1, 2, 3, 4, 5]})
3348
+ # df.with_columns(
3349
+ # Polars.col("x").truediv(2).alias("x/2"),
3350
+ # Polars.col("x").floordiv(2).alias("x//2")
3351
+ # )
3352
+ # # =>
3353
+ # # shape: (5, 3)
3354
+ # # ┌─────┬─────┬──────┐
3355
+ # # │ x ┆ x/2 ┆ x//2 │
3356
+ # # │ --- ┆ --- ┆ --- │
3357
+ # # │ i64 ┆ f64 ┆ i64 │
3358
+ # # ╞═════╪═════╪══════╡
3359
+ # # │ 1 ┆ 0.5 ┆ 0 │
3360
+ # # │ 2 ┆ 1.0 ┆ 1 │
3361
+ # # │ 3 ┆ 1.5 ┆ 1 │
3362
+ # # │ 4 ┆ 2.0 ┆ 2 │
3363
+ # # │ 5 ┆ 2.5 ┆ 2 │
3364
+ # # └─────┴─────┴──────┘
3365
+ def floordiv(other)
3366
+ _from_rbexpr(_rbexpr.floordiv(_to_rbexpr(other)))
3367
+ end
3368
+
3369
+ # Method equivalent of modulus operator `expr % other`.
3370
+ #
3371
+ # @param other [Object]
3372
+ # Numeric literal or expression value.
3373
+ #
3374
+ # @return [Expr]
3375
+ #
3376
+ # @example
3377
+ # df = Polars::DataFrame.new({"x" => [0, 1, 2, 3, 4]})
3378
+ # df.with_columns(Polars.col("x").mod(2).alias("x%2"))
3379
+ # # =>
3380
+ # # shape: (5, 2)
3381
+ # # ┌─────┬─────┐
3382
+ # # │ x ┆ x%2 │
3383
+ # # │ --- ┆ --- │
3384
+ # # │ i64 ┆ i64 │
3385
+ # # ╞═════╪═════╡
3386
+ # # │ 0 ┆ 0 │
3387
+ # # │ 1 ┆ 1 │
3388
+ # # │ 2 ┆ 0 │
3389
+ # # │ 3 ┆ 1 │
3390
+ # # │ 4 ┆ 0 │
3391
+ # # └─────┴─────┘
3392
+ def mod(other)
3393
+ self % other
3394
+ end
3395
+
3396
+ # Method equivalent of multiplication operator `expr * other`.
3397
+ #
3398
+ # @param other [Object]
3399
+ # Numeric literal or expression value.
3400
+ #
3401
+ # @return [Expr]
3402
+ #
3403
+ # @example
3404
+ # df = Polars::DataFrame.new({"x" => [1, 2, 4, 8, 16]})
3405
+ # df.with_columns(
3406
+ # Polars.col("x").mul(2).alias("x*2"),
3407
+ # Polars.col("x").mul(Polars.col("x").log(2)).alias("x * xlog2"),
3408
+ # )
3409
+ # # =>
3410
+ # # shape: (5, 3)
3411
+ # # ┌─────┬─────┬───────────┐
3412
+ # # │ x ┆ x*2 ┆ x * xlog2 │
3413
+ # # │ --- ┆ --- ┆ --- │
3414
+ # # │ i64 ┆ i64 ┆ f64 │
3415
+ # # ╞═════╪═════╪═══════════╡
3416
+ # # │ 1 ┆ 2 ┆ 0.0 │
3417
+ # # │ 2 ┆ 4 ┆ 2.0 │
3418
+ # # │ 4 ┆ 8 ┆ 8.0 │
3419
+ # # │ 8 ┆ 16 ┆ 24.0 │
3420
+ # # │ 16 ┆ 32 ┆ 64.0 │
3421
+ # # └─────┴─────┴───────────┘
3422
+ def mul(other)
3423
+ self * other
3424
+ end
3425
+
3426
+ # Method equivalent of subtraction operator `expr - other`.
3427
+ #
3428
+ # @param other [Object]
3429
+ # Numeric literal or expression value.
3430
+ #
3431
+ # @return [Expr]
3432
+ #
3433
+ # @example
3434
+ # df = Polars::DataFrame.new({"x" => [0, 1, 2, 3, 4]})
3435
+ # df.with_columns(
3436
+ # Polars.col("x").sub(2).alias("x-2"),
3437
+ # Polars.col("x").sub(Polars.col("x").cum_sum).alias("x-expr"),
3438
+ # )
3439
+ # # =>
3440
+ # # shape: (5, 3)
3441
+ # # ┌─────┬─────┬────────┐
3442
+ # # │ x ┆ x-2 ┆ x-expr │
3443
+ # # │ --- ┆ --- ┆ --- │
3444
+ # # │ i64 ┆ i64 ┆ i64 │
3445
+ # # ╞═════╪═════╪════════╡
3446
+ # # │ 0 ┆ -2 ┆ 0 │
3447
+ # # │ 1 ┆ -1 ┆ 0 │
3448
+ # # │ 2 ┆ 0 ┆ -1 │
3449
+ # # │ 3 ┆ 1 ┆ -3 │
3450
+ # # │ 4 ┆ 2 ┆ -6 │
3451
+ # # └─────┴─────┴────────┘
3452
+ def sub(other)
3453
+ self - other
3454
+ end
3455
+
3456
+ # Method equivalent of unary minus operator `-expr`.
3457
+ #
3458
+ # @return [Expr]
3459
+ #
3460
+ # @example
3461
+ # df = Polars::DataFrame.new({"a" => [-1, 0, 2, nil]})
3462
+ # df.with_columns(Polars.col("a").neg)
3029
3463
  # # =>
3030
3464
  # # shape: (4, 1)
3031
3465
  # # ┌──────┐
3032
- # # │ foo
3466
+ # # │ a
3033
3467
  # # │ --- │
3034
- # # │ f64
3468
+ # # │ i64
3035
3469
  # # ╞══════╡
3036
- # # │ 1.0
3037
- # # │ 8.0
3038
- # # │ 27.0
3039
- # # │ 64.0
3470
+ # # │ 1
3471
+ # # │ 0
3472
+ # # │ -2
3473
+ # # │ null
3040
3474
  # # └──────┘
3475
+ def neg
3476
+ -self
3477
+ end
3478
+
3479
+ # Method equivalent of float division operator `expr / other`.
3480
+ #
3481
+ # @param other [Object]
3482
+ # Numeric literal or expression value.
3483
+ #
3484
+ # @return [Expr]
3485
+ #
3486
+ # @example
3487
+ # df = Polars::DataFrame.new(
3488
+ # {"x" => [-2, -1, 0, 1, 2], "y" => [0.5, 0.0, 0.0, -4.0, -0.5]}
3489
+ # )
3490
+ # df.with_columns(
3491
+ # Polars.col("x").truediv(2).alias("x/2"),
3492
+ # Polars.col("x").truediv(Polars.col("y")).alias("x/y")
3493
+ # )
3494
+ # # =>
3495
+ # # shape: (5, 4)
3496
+ # # ┌─────┬──────┬──────┬───────┐
3497
+ # # │ x ┆ y ┆ x/2 ┆ x/y │
3498
+ # # │ --- ┆ --- ┆ --- ┆ --- │
3499
+ # # │ i64 ┆ f64 ┆ f64 ┆ f64 │
3500
+ # # ╞═════╪══════╪══════╪═══════╡
3501
+ # # │ -2 ┆ 0.5 ┆ -1.0 ┆ -4.0 │
3502
+ # # │ -1 ┆ 0.0 ┆ -0.5 ┆ -inf │
3503
+ # # │ 0 ┆ 0.0 ┆ 0.0 ┆ NaN │
3504
+ # # │ 1 ┆ -4.0 ┆ 0.5 ┆ -0.25 │
3505
+ # # │ 2 ┆ -0.5 ┆ 1.0 ┆ -4.0 │
3506
+ # # └─────┴──────┴──────┴───────┘
3507
+ def truediv(other)
3508
+ self / other
3509
+ end
3510
+
3511
+ # Raise expression to the power of exponent.
3512
+ #
3513
+ # @return [Expr]
3514
+ #
3515
+ # @example
3516
+ # df = Polars::DataFrame.new({"x" => [1, 2, 4, 8]})
3517
+ # df.with_columns(
3518
+ # Polars.col("x").pow(3).alias("cube"),
3519
+ # Polars.col("x").pow(Polars.col("x").log(2)).alias("x ** xlog2")
3520
+ # )
3521
+ # # =>
3522
+ # # shape: (4, 3)
3523
+ # # ┌─────┬──────┬────────────┐
3524
+ # # │ x ┆ cube ┆ x ** xlog2 │
3525
+ # # │ --- ┆ --- ┆ --- │
3526
+ # # │ i64 ┆ i64 ┆ f64 │
3527
+ # # ╞═════╪══════╪════════════╡
3528
+ # # │ 1 ┆ 1 ┆ 1.0 │
3529
+ # # │ 2 ┆ 8 ┆ 2.0 │
3530
+ # # │ 4 ┆ 64 ┆ 16.0 │
3531
+ # # │ 8 ┆ 512 ┆ 512.0 │
3532
+ # # └─────┴──────┴────────────┘
3041
3533
  def pow(exponent)
3042
- exponent = Utils.expr_to_lit_or_expr(exponent)
3043
- wrap_expr(_rbexpr.pow(exponent._rbexpr))
3534
+ self**exponent
3535
+ end
3536
+
3537
+ # Method equivalent of bitwise exclusive-or operator `expr ^ other`.
3538
+ #
3539
+ # @param other [Object]
3540
+ # Integer or boolean value; accepts expression input.
3541
+ #
3542
+ # @return [Expr]
3543
+ #
3544
+ # @example
3545
+ # df = Polars::DataFrame.new(
3546
+ # {"x" => [true, false, true, false], "y" => [true, true, false, false]}
3547
+ # )
3548
+ # df.with_columns(Polars.col("x").xor(Polars.col("y")).alias("x ^ y"))
3549
+ # # =>
3550
+ # # shape: (4, 3)
3551
+ # # ┌───────┬───────┬───────┐
3552
+ # # │ x ┆ y ┆ x ^ y │
3553
+ # # │ --- ┆ --- ┆ --- │
3554
+ # # │ bool ┆ bool ┆ bool │
3555
+ # # ╞═══════╪═══════╪═══════╡
3556
+ # # │ true ┆ true ┆ false │
3557
+ # # │ false ┆ true ┆ true │
3558
+ # # │ true ┆ false ┆ true │
3559
+ # # │ false ┆ false ┆ false │
3560
+ # # └───────┴───────┴───────┘
3561
+ def xor(other)
3562
+ self ^ other
3044
3563
  end
3045
3564
 
3046
3565
  # Check if elements of this expression are present in the other Series.
@@ -3076,7 +3595,7 @@ module Polars
3076
3595
  else
3077
3596
  other = Utils.expr_to_lit_or_expr(other, str_to_lit: false)
3078
3597
  end
3079
- wrap_expr(_rbexpr.is_in(other._rbexpr))
3598
+ _from_rbexpr(_rbexpr.is_in(other._rbexpr))
3080
3599
  end
3081
3600
  alias_method :in?, :is_in
3082
3601
 
@@ -3112,7 +3631,7 @@ module Polars
3112
3631
  # # └─────────────────┘
3113
3632
  def repeat_by(by)
3114
3633
  by = Utils.expr_to_lit_or_expr(by, str_to_lit: false)
3115
- wrap_expr(_rbexpr.repeat_by(by._rbexpr))
3634
+ _from_rbexpr(_rbexpr.repeat_by(by._rbexpr))
3116
3635
  end
3117
3636
 
3118
3637
  # Check if this expression is between start and end.
@@ -3238,7 +3757,7 @@ module Polars
3238
3757
  k1 = seed_1.nil? ? seed : seed_1
3239
3758
  k2 = seed_2.nil? ? seed : seed_2
3240
3759
  k3 = seed_3.nil? ? seed : seed_3
3241
- wrap_expr(_rbexpr._hash(k0, k1, k2, k3))
3760
+ _from_rbexpr(_rbexpr._hash(k0, k1, k2, k3))
3242
3761
  end
3243
3762
 
3244
3763
  # Reinterpret the underlying bits as a signed/unsigned integer.
@@ -3272,7 +3791,7 @@ module Polars
3272
3791
  # # │ 2 ┆ 2 │
3273
3792
  # # └───────────────┴──────────┘
3274
3793
  def reinterpret(signed: false)
3275
- wrap_expr(_rbexpr.reinterpret(signed))
3794
+ _from_rbexpr(_rbexpr.reinterpret(signed))
3276
3795
  end
3277
3796
 
3278
3797
  # Print the value that this expression evaluates to and pass on the value.
@@ -3335,7 +3854,7 @@ module Polars
3335
3854
  # # │ 3.0 ┆ 3.0 │
3336
3855
  # # └─────┴─────┘
3337
3856
  def interpolate(method: "linear")
3338
- wrap_expr(_rbexpr.interpolate(method))
3857
+ _from_rbexpr(_rbexpr.interpolate(method))
3339
3858
  end
3340
3859
 
3341
3860
  # Apply a rolling min (moving min) over the values in this array.
@@ -3415,12 +3934,12 @@ module Polars
3415
3934
  min_periods: nil,
3416
3935
  center: false,
3417
3936
  by: nil,
3418
- closed: "left"
3937
+ closed: nil
3419
3938
  )
3420
3939
  window_size, min_periods = _prepare_rolling_window_args(
3421
3940
  window_size, min_periods
3422
3941
  )
3423
- wrap_expr(
3942
+ _from_rbexpr(
3424
3943
  _rbexpr.rolling_min(
3425
3944
  window_size, weights, min_periods, center, by, closed
3426
3945
  )
@@ -3504,12 +4023,12 @@ module Polars
3504
4023
  min_periods: nil,
3505
4024
  center: false,
3506
4025
  by: nil,
3507
- closed: "left"
4026
+ closed: nil
3508
4027
  )
3509
4028
  window_size, min_periods = _prepare_rolling_window_args(
3510
4029
  window_size, min_periods
3511
4030
  )
3512
- wrap_expr(
4031
+ _from_rbexpr(
3513
4032
  _rbexpr.rolling_max(
3514
4033
  window_size, weights, min_periods, center, by, closed
3515
4034
  )
@@ -3593,12 +4112,12 @@ module Polars
3593
4112
  min_periods: nil,
3594
4113
  center: false,
3595
4114
  by: nil,
3596
- closed: "left"
4115
+ closed: nil
3597
4116
  )
3598
4117
  window_size, min_periods = _prepare_rolling_window_args(
3599
4118
  window_size, min_periods
3600
4119
  )
3601
- wrap_expr(
4120
+ _from_rbexpr(
3602
4121
  _rbexpr.rolling_mean(
3603
4122
  window_size, weights, min_periods, center, by, closed
3604
4123
  )
@@ -3682,12 +4201,12 @@ module Polars
3682
4201
  min_periods: nil,
3683
4202
  center: false,
3684
4203
  by: nil,
3685
- closed: "left"
4204
+ closed: nil
3686
4205
  )
3687
4206
  window_size, min_periods = _prepare_rolling_window_args(
3688
4207
  window_size, min_periods
3689
4208
  )
3690
- wrap_expr(
4209
+ _from_rbexpr(
3691
4210
  _rbexpr.rolling_sum(
3692
4211
  window_size, weights, min_periods, center, by, closed
3693
4212
  )
@@ -3771,14 +4290,14 @@ module Polars
3771
4290
  min_periods: nil,
3772
4291
  center: false,
3773
4292
  by: nil,
3774
- closed: "left",
4293
+ closed: nil,
3775
4294
  ddof: 1,
3776
4295
  warn_if_unsorted: true
3777
4296
  )
3778
4297
  window_size, min_periods = _prepare_rolling_window_args(
3779
4298
  window_size, min_periods
3780
4299
  )
3781
- wrap_expr(
4300
+ _from_rbexpr(
3782
4301
  _rbexpr.rolling_std(
3783
4302
  window_size, weights, min_periods, center, by, closed, ddof, warn_if_unsorted
3784
4303
  )
@@ -3862,14 +4381,14 @@ module Polars
3862
4381
  min_periods: nil,
3863
4382
  center: false,
3864
4383
  by: nil,
3865
- closed: "left",
4384
+ closed: nil,
3866
4385
  ddof: 1,
3867
4386
  warn_if_unsorted: true
3868
4387
  )
3869
4388
  window_size, min_periods = _prepare_rolling_window_args(
3870
4389
  window_size, min_periods
3871
4390
  )
3872
- wrap_expr(
4391
+ _from_rbexpr(
3873
4392
  _rbexpr.rolling_var(
3874
4393
  window_size, weights, min_periods, center, by, closed, ddof, warn_if_unsorted
3875
4394
  )
@@ -3949,13 +4468,13 @@ module Polars
3949
4468
  min_periods: nil,
3950
4469
  center: false,
3951
4470
  by: nil,
3952
- closed: "left",
4471
+ closed: nil,
3953
4472
  warn_if_unsorted: true
3954
4473
  )
3955
4474
  window_size, min_periods = _prepare_rolling_window_args(
3956
4475
  window_size, min_periods
3957
4476
  )
3958
- wrap_expr(
4477
+ _from_rbexpr(
3959
4478
  _rbexpr.rolling_median(
3960
4479
  window_size, weights, min_periods, center, by, closed, warn_if_unsorted
3961
4480
  )
@@ -4041,13 +4560,13 @@ module Polars
4041
4560
  min_periods: nil,
4042
4561
  center: false,
4043
4562
  by: nil,
4044
- closed: "left",
4563
+ closed: nil,
4045
4564
  warn_if_unsorted: true
4046
4565
  )
4047
4566
  window_size, min_periods = _prepare_rolling_window_args(
4048
4567
  window_size, min_periods
4049
4568
  )
4050
- wrap_expr(
4569
+ _from_rbexpr(
4051
4570
  _rbexpr.rolling_quantile(
4052
4571
  quantile, interpolation, window_size, weights, min_periods, center, by, closed, warn_if_unsorted
4053
4572
  )
@@ -4111,7 +4630,7 @@ module Polars
4111
4630
  # if min_periods.nil?
4112
4631
  # min_periods = window_size
4113
4632
  # end
4114
- # wrap_expr(
4633
+ # _from_rbexpr(
4115
4634
  # _rbexpr.rolling_apply(
4116
4635
  # function, window_size, weights, min_periods, center
4117
4636
  # )
@@ -4127,7 +4646,7 @@ module Polars
4127
4646
  #
4128
4647
  # @return [Expr]
4129
4648
  def rolling_skew(window_size, bias: true)
4130
- wrap_expr(_rbexpr.rolling_skew(window_size, bias))
4649
+ _from_rbexpr(_rbexpr.rolling_skew(window_size, bias))
4131
4650
  end
4132
4651
 
4133
4652
  # Compute absolute values.
@@ -4154,7 +4673,7 @@ module Polars
4154
4673
  # # │ 2.0 │
4155
4674
  # # └─────┘
4156
4675
  def abs
4157
- wrap_expr(_rbexpr.abs)
4676
+ _from_rbexpr(_rbexpr.abs)
4158
4677
  end
4159
4678
 
4160
4679
  # Get the index values that would sort this column.
@@ -4212,6 +4731,8 @@ module Polars
4212
4731
  # on the order that the values occur in the Series.
4213
4732
  # @param reverse [Boolean]
4214
4733
  # Reverse the operation.
4734
+ # @param seed [Integer]
4735
+ # If `method: "random"`, use this as seed.
4215
4736
  #
4216
4737
  # @return [Expr]
4217
4738
  #
@@ -4249,7 +4770,7 @@ module Polars
4249
4770
  # # │ 5 │
4250
4771
  # # └─────┘
4251
4772
  def rank(method: "average", reverse: false, seed: nil)
4252
- wrap_expr(_rbexpr.rank(method, reverse, seed))
4773
+ _from_rbexpr(_rbexpr.rank(method, reverse, seed))
4253
4774
  end
4254
4775
 
4255
4776
  # Calculate the n-th discrete difference.
@@ -4280,7 +4801,7 @@ module Polars
4280
4801
  # # │ 20 │
4281
4802
  # # └──────┘
4282
4803
  def diff(n: 1, null_behavior: "ignore")
4283
- wrap_expr(_rbexpr.diff(n, null_behavior))
4804
+ _from_rbexpr(_rbexpr.diff(n, null_behavior))
4284
4805
  end
4285
4806
 
4286
4807
  # Computes percentage change between values.
@@ -4317,7 +4838,7 @@ module Polars
4317
4838
  # # └──────┴────────────┘
4318
4839
  def pct_change(n: 1)
4319
4840
  n = Utils.parse_as_expression(n)
4320
- wrap_expr(_rbexpr.pct_change(n))
4841
+ _from_rbexpr(_rbexpr.pct_change(n))
4321
4842
  end
4322
4843
 
4323
4844
  # Compute the sample skewness of a data set.
@@ -4346,7 +4867,7 @@ module Polars
4346
4867
  # # │ 0.343622 │
4347
4868
  # # └──────────┘
4348
4869
  def skew(bias: true)
4349
- wrap_expr(_rbexpr.skew(bias))
4870
+ _from_rbexpr(_rbexpr.skew(bias))
4350
4871
  end
4351
4872
 
4352
4873
  # Compute the kurtosis (Fisher or Pearson) of a dataset.
@@ -4378,7 +4899,7 @@ module Polars
4378
4899
  # # │ -1.153061 │
4379
4900
  # # └───────────┘
4380
4901
  def kurtosis(fisher: true, bias: true)
4381
- wrap_expr(_rbexpr.kurtosis(fisher, bias))
4902
+ _from_rbexpr(_rbexpr.kurtosis(fisher, bias))
4382
4903
  end
4383
4904
 
4384
4905
  # Set values outside the given boundaries to the boundary value.
@@ -4415,7 +4936,7 @@ module Polars
4415
4936
  if !upper_bound.nil?
4416
4937
  upper_bound = Utils.parse_as_expression(upper_bound, str_as_lit: true)
4417
4938
  end
4418
- wrap_expr(_rbexpr.clip(lower_bound, upper_bound))
4939
+ _from_rbexpr(_rbexpr.clip(lower_bound, upper_bound))
4419
4940
  end
4420
4941
 
4421
4942
  # Clip (limit) the values in an array to a `min` boundary.
@@ -4500,7 +5021,7 @@ module Polars
4500
5021
  # # │ -9223372036854775808 │
4501
5022
  # # └──────────────────────┘
4502
5023
  def lower_bound
4503
- wrap_expr(_rbexpr.lower_bound)
5024
+ _from_rbexpr(_rbexpr.lower_bound)
4504
5025
  end
4505
5026
 
4506
5027
  # Calculate the upper bound.
@@ -4523,7 +5044,7 @@ module Polars
4523
5044
  # # │ 9223372036854775807 │
4524
5045
  # # └─────────────────────┘
4525
5046
  def upper_bound
4526
- wrap_expr(_rbexpr.upper_bound)
5047
+ _from_rbexpr(_rbexpr.upper_bound)
4527
5048
  end
4528
5049
 
4529
5050
  # Compute the element-wise indication of the sign.
@@ -4547,7 +5068,7 @@ module Polars
4547
5068
  # # │ null │
4548
5069
  # # └──────┘
4549
5070
  def sign
4550
- wrap_expr(_rbexpr.sign)
5071
+ _from_rbexpr(_rbexpr.sign)
4551
5072
  end
4552
5073
 
4553
5074
  # Compute the element-wise value for the sine.
@@ -4567,7 +5088,7 @@ module Polars
4567
5088
  # # │ 0.0 │
4568
5089
  # # └─────┘
4569
5090
  def sin
4570
- wrap_expr(_rbexpr.sin)
5091
+ _from_rbexpr(_rbexpr.sin)
4571
5092
  end
4572
5093
 
4573
5094
  # Compute the element-wise value for the cosine.
@@ -4587,7 +5108,7 @@ module Polars
4587
5108
  # # │ 1.0 │
4588
5109
  # # └─────┘
4589
5110
  def cos
4590
- wrap_expr(_rbexpr.cos)
5111
+ _from_rbexpr(_rbexpr.cos)
4591
5112
  end
4592
5113
 
4593
5114
  # Compute the element-wise value for the tangent.
@@ -4607,7 +5128,7 @@ module Polars
4607
5128
  # # │ 1.557408 │
4608
5129
  # # └──────────┘
4609
5130
  def tan
4610
- wrap_expr(_rbexpr.tan)
5131
+ _from_rbexpr(_rbexpr.tan)
4611
5132
  end
4612
5133
 
4613
5134
  # Compute the element-wise value for the inverse sine.
@@ -4627,7 +5148,7 @@ module Polars
4627
5148
  # # │ 1.570796 │
4628
5149
  # # └──────────┘
4629
5150
  def arcsin
4630
- wrap_expr(_rbexpr.arcsin)
5151
+ _from_rbexpr(_rbexpr.arcsin)
4631
5152
  end
4632
5153
 
4633
5154
  # Compute the element-wise value for the inverse cosine.
@@ -4647,7 +5168,7 @@ module Polars
4647
5168
  # # │ 1.570796 │
4648
5169
  # # └──────────┘
4649
5170
  def arccos
4650
- wrap_expr(_rbexpr.arccos)
5171
+ _from_rbexpr(_rbexpr.arccos)
4651
5172
  end
4652
5173
 
4653
5174
  # Compute the element-wise value for the inverse tangent.
@@ -4667,7 +5188,7 @@ module Polars
4667
5188
  # # │ 0.785398 │
4668
5189
  # # └──────────┘
4669
5190
  def arctan
4670
- wrap_expr(_rbexpr.arctan)
5191
+ _from_rbexpr(_rbexpr.arctan)
4671
5192
  end
4672
5193
 
4673
5194
  # Compute the element-wise value for the hyperbolic sine.
@@ -4687,7 +5208,7 @@ module Polars
4687
5208
  # # │ 1.175201 │
4688
5209
  # # └──────────┘
4689
5210
  def sinh
4690
- wrap_expr(_rbexpr.sinh)
5211
+ _from_rbexpr(_rbexpr.sinh)
4691
5212
  end
4692
5213
 
4693
5214
  # Compute the element-wise value for the hyperbolic cosine.
@@ -4707,7 +5228,7 @@ module Polars
4707
5228
  # # │ 1.543081 │
4708
5229
  # # └──────────┘
4709
5230
  def cosh
4710
- wrap_expr(_rbexpr.cosh)
5231
+ _from_rbexpr(_rbexpr.cosh)
4711
5232
  end
4712
5233
 
4713
5234
  # Compute the element-wise value for the hyperbolic tangent.
@@ -4727,7 +5248,7 @@ module Polars
4727
5248
  # # │ 0.761594 │
4728
5249
  # # └──────────┘
4729
5250
  def tanh
4730
- wrap_expr(_rbexpr.tanh)
5251
+ _from_rbexpr(_rbexpr.tanh)
4731
5252
  end
4732
5253
 
4733
5254
  # Compute the element-wise value for the inverse hyperbolic sine.
@@ -4747,7 +5268,7 @@ module Polars
4747
5268
  # # │ 0.881374 │
4748
5269
  # # └──────────┘
4749
5270
  def arcsinh
4750
- wrap_expr(_rbexpr.arcsinh)
5271
+ _from_rbexpr(_rbexpr.arcsinh)
4751
5272
  end
4752
5273
 
4753
5274
  # Compute the element-wise value for the inverse hyperbolic cosine.
@@ -4767,7 +5288,7 @@ module Polars
4767
5288
  # # │ 0.0 │
4768
5289
  # # └─────┘
4769
5290
  def arccosh
4770
- wrap_expr(_rbexpr.arccosh)
5291
+ _from_rbexpr(_rbexpr.arccosh)
4771
5292
  end
4772
5293
 
4773
5294
  # Compute the element-wise value for the inverse hyperbolic tangent.
@@ -4787,7 +5308,7 @@ module Polars
4787
5308
  # # │ inf │
4788
5309
  # # └─────┘
4789
5310
  def arctanh
4790
- wrap_expr(_rbexpr.arctanh)
5311
+ _from_rbexpr(_rbexpr.arctanh)
4791
5312
  end
4792
5313
 
4793
5314
  # Reshape this Expr to a flat Series or a Series of Lists.
@@ -4813,7 +5334,7 @@ module Polars
4813
5334
  # # │ [7, 8, 9] │
4814
5335
  # # └───────────┘
4815
5336
  def reshape(dims)
4816
- wrap_expr(_rbexpr.reshape(dims))
5337
+ _from_rbexpr(_rbexpr.reshape(dims))
4817
5338
  end
4818
5339
 
4819
5340
  # Shuffle the contents of this expr.
@@ -4842,7 +5363,7 @@ module Polars
4842
5363
  if seed.nil?
4843
5364
  seed = rand(10000)
4844
5365
  end
4845
- wrap_expr(_rbexpr.shuffle(seed))
5366
+ _from_rbexpr(_rbexpr.shuffle(seed))
4846
5367
  end
4847
5368
 
4848
5369
  # Sample from this expression.
@@ -4888,14 +5409,14 @@ module Polars
4888
5409
 
4889
5410
  if !n.nil? && frac.nil?
4890
5411
  n = Utils.parse_as_expression(n)
4891
- return wrap_expr(_rbexpr.sample_n(n, with_replacement, shuffle, seed))
5412
+ return _from_rbexpr(_rbexpr.sample_n(n, with_replacement, shuffle, seed))
4892
5413
  end
4893
5414
 
4894
5415
  if frac.nil?
4895
5416
  frac = 1.0
4896
5417
  end
4897
5418
  frac = Utils.parse_as_expression(frac)
4898
- wrap_expr(
5419
+ _from_rbexpr(
4899
5420
  _rbexpr.sample_frac(frac, with_replacement, shuffle, seed)
4900
5421
  )
4901
5422
  end
@@ -4928,7 +5449,7 @@ module Polars
4928
5449
  ignore_nulls: true
4929
5450
  )
4930
5451
  alpha = _prepare_alpha(com, span, half_life, alpha)
4931
- wrap_expr(_rbexpr.ewm_mean(alpha, adjust, min_periods, ignore_nulls))
5452
+ _from_rbexpr(_rbexpr.ewm_mean(alpha, adjust, min_periods, ignore_nulls))
4932
5453
  end
4933
5454
 
4934
5455
  # Exponentially-weighted moving standard deviation.
@@ -4960,7 +5481,7 @@ module Polars
4960
5481
  ignore_nulls: true
4961
5482
  )
4962
5483
  alpha = _prepare_alpha(com, span, half_life, alpha)
4963
- wrap_expr(_rbexpr.ewm_std(alpha, adjust, bias, min_periods, ignore_nulls))
5484
+ _from_rbexpr(_rbexpr.ewm_std(alpha, adjust, bias, min_periods, ignore_nulls))
4964
5485
  end
4965
5486
 
4966
5487
  # Exponentially-weighted moving variance.
@@ -4992,7 +5513,7 @@ module Polars
4992
5513
  ignore_nulls: true
4993
5514
  )
4994
5515
  alpha = _prepare_alpha(com, span, half_life, alpha)
4995
- wrap_expr(_rbexpr.ewm_var(alpha, adjust, bias, min_periods, ignore_nulls))
5516
+ _from_rbexpr(_rbexpr.ewm_var(alpha, adjust, bias, min_periods, ignore_nulls))
4996
5517
  end
4997
5518
 
4998
5519
  # Extend the Series with given number of values.
@@ -5022,7 +5543,7 @@ module Polars
5022
5543
  # # │ 99 │
5023
5544
  # # └────────┘
5024
5545
  def extend_constant(value, n)
5025
- wrap_expr(_rbexpr.extend_constant(value, n))
5546
+ _from_rbexpr(_rbexpr.extend_constant(value, n))
5026
5547
  end
5027
5548
 
5028
5549
  # Count all unique values and create a struct mapping value to count.
@@ -5058,7 +5579,7 @@ module Polars
5058
5579
  # # │ {"a",1} │
5059
5580
  # # └───────────┘
5060
5581
  def value_counts(multithreaded: false, sort: false)
5061
- wrap_expr(_rbexpr.value_counts(multithreaded, sort))
5582
+ _from_rbexpr(_rbexpr.value_counts(multithreaded, sort))
5062
5583
  end
5063
5584
 
5064
5585
  # Return a count of the unique values in the order of appearance.
@@ -5091,7 +5612,7 @@ module Polars
5091
5612
  # # │ 3 │
5092
5613
  # # └─────┘
5093
5614
  def unique_counts
5094
- wrap_expr(_rbexpr.unique_counts)
5615
+ _from_rbexpr(_rbexpr.unique_counts)
5095
5616
  end
5096
5617
 
5097
5618
  # Compute the logarithm to a given base.
@@ -5116,7 +5637,7 @@ module Polars
5116
5637
  # # │ 1.584963 │
5117
5638
  # # └──────────┘
5118
5639
  def log(base = Math::E)
5119
- wrap_expr(_rbexpr.log(base))
5640
+ _from_rbexpr(_rbexpr.log(base))
5120
5641
  end
5121
5642
 
5122
5643
  # Computes the entropy.
@@ -5155,7 +5676,7 @@ module Polars
5155
5676
  # # │ -6.754888 │
5156
5677
  # # └───────────┘
5157
5678
  def entropy(base: 2, normalize: true)
5158
- wrap_expr(_rbexpr.entropy(base, normalize))
5679
+ _from_rbexpr(_rbexpr.entropy(base, normalize))
5159
5680
  end
5160
5681
 
5161
5682
  # Run an expression over a sliding window that increases `1` slot every iteration.
@@ -5193,16 +5714,16 @@ module Polars
5193
5714
  # # ┌────────┐
5194
5715
  # # │ values │
5195
5716
  # # │ --- │
5196
- # # │ f64
5717
+ # # │ i64
5197
5718
  # # ╞════════╡
5198
- # # │ 0.0
5199
- # # │ -3.0
5200
- # # │ -8.0
5201
- # # │ -15.0
5202
- # # │ -24.0
5719
+ # # │ 0
5720
+ # # │ -3
5721
+ # # │ -8
5722
+ # # │ -15
5723
+ # # │ -24
5203
5724
  # # └────────┘
5204
5725
  def cumulative_eval(expr, min_periods: 1, parallel: false)
5205
- wrap_expr(
5726
+ _from_rbexpr(
5206
5727
  _rbexpr.cumulative_eval(expr._rbexpr, min_periods, parallel)
5207
5728
  )
5208
5729
  end
@@ -5233,7 +5754,7 @@ module Polars
5233
5754
  # # │ 3 │
5234
5755
  # # └────────┘
5235
5756
  def set_sorted(descending: false)
5236
- wrap_expr(_rbexpr.set_sorted_flag(descending))
5757
+ _from_rbexpr(_rbexpr.set_sorted_flag(descending))
5237
5758
  end
5238
5759
 
5239
5760
  # Aggregate to list.
@@ -5258,7 +5779,7 @@ module Polars
5258
5779
  # # │ [1, 2, 3] ┆ [4, 5, 6] │
5259
5780
  # # └───────────┴───────────┘
5260
5781
  def implode
5261
- wrap_expr(_rbexpr.implode)
5782
+ _from_rbexpr(_rbexpr.implode)
5262
5783
  end
5263
5784
 
5264
5785
  # Shrink numeric columns to the minimal required datatype.
@@ -5293,7 +5814,169 @@ module Polars
5293
5814
  # # │ 3 ┆ 8589934592 ┆ 1073741824 ┆ 112 ┆ 129 ┆ c ┆ 0.12 ┆ false │
5294
5815
  # # └─────┴────────────┴────────────┴──────┴──────┴─────┴──────┴───────┘
5295
5816
  def shrink_dtype
5296
- wrap_expr(_rbexpr.shrink_dtype)
5817
+ _from_rbexpr(_rbexpr.shrink_dtype)
5818
+ end
5819
+
5820
+ # Replace values by different values.
5821
+ #
5822
+ # @param old [Object]
5823
+ # Value or sequence of values to replace.
5824
+ # Accepts expression input. Sequences are parsed as Series,
5825
+ # other non-expression inputs are parsed as literals.
5826
+ # Also accepts a mapping of values to their replacement.
5827
+ # @param new [Object]
5828
+ # Value or sequence of values to replace by.
5829
+ # Accepts expression input. Sequences are parsed as Series,
5830
+ # other non-expression inputs are parsed as literals.
5831
+ # Length must match the length of `old` or have length 1.
5832
+ # @param default [Object]
5833
+ # Set values that were not replaced to this value.
5834
+ # Defaults to keeping the original value.
5835
+ # Accepts expression input. Non-expression inputs are parsed as literals.
5836
+ # @param return_dtype [Object]
5837
+ # The data type of the resulting expression. If set to `nil` (default),
5838
+ # the data type is determined automatically based on the other inputs.
5839
+ #
5840
+ # @return [Expr]
5841
+ #
5842
+ # @example Replace a single value by another value. Values that were not replaced remain unchanged.
5843
+ # df = Polars::DataFrame.new({"a" => [1, 2, 2, 3]})
5844
+ # df.with_columns(replaced: Polars.col("a").replace(2, 100))
5845
+ # # =>
5846
+ # # shape: (4, 2)
5847
+ # # ┌─────┬──────────┐
5848
+ # # │ a ┆ replaced │
5849
+ # # │ --- ┆ --- │
5850
+ # # │ i64 ┆ i64 │
5851
+ # # ╞═════╪══════════╡
5852
+ # # │ 1 ┆ 1 │
5853
+ # # │ 2 ┆ 100 │
5854
+ # # │ 2 ┆ 100 │
5855
+ # # │ 3 ┆ 3 │
5856
+ # # └─────┴──────────┘
5857
+ #
5858
+ # @example Replace multiple values by passing sequences to the `old` and `new` parameters.
5859
+ # df.with_columns(replaced: Polars.col("a").replace([2, 3], [100, 200]))
5860
+ # # =>
5861
+ # # shape: (4, 2)
5862
+ # # ┌─────┬──────────┐
5863
+ # # │ a ┆ replaced │
5864
+ # # │ --- ┆ --- │
5865
+ # # │ i64 ┆ i64 │
5866
+ # # ╞═════╪══════════╡
5867
+ # # │ 1 ┆ 1 │
5868
+ # # │ 2 ┆ 100 │
5869
+ # # │ 2 ┆ 100 │
5870
+ # # │ 3 ┆ 200 │
5871
+ # # └─────┴──────────┘
5872
+ #
5873
+ # @example Passing a mapping with replacements is also supported as syntactic sugar. Specify a default to set all values that were not matched.
5874
+ # mapping = {2 => 100, 3 => 200}
5875
+ # df.with_columns(replaced: Polars.col("a").replace(mapping, default: -1))
5876
+ # # =>
5877
+ # # shape: (4, 2)
5878
+ # # ┌─────┬──────────┐
5879
+ # # │ a ┆ replaced │
5880
+ # # │ --- ┆ --- │
5881
+ # # │ i64 ┆ i64 │
5882
+ # # ╞═════╪══════════╡
5883
+ # # │ 1 ┆ -1 │
5884
+ # # │ 2 ┆ 100 │
5885
+ # # │ 2 ┆ 100 │
5886
+ # # │ 3 ┆ 200 │
5887
+ # # └─────┴──────────┘
5888
+ #
5889
+ # @example Replacing by values of a different data type sets the return type based on a combination of the `new` data type and either the original data type or the default data type if it was set.
5890
+ # df = Polars::DataFrame.new({"a" => ["x", "y", "z"]})
5891
+ # mapping = {"x" => 1, "y" => 2, "z" => 3}
5892
+ # df.with_columns(replaced: Polars.col("a").replace(mapping))
5893
+ # # =>
5894
+ # # shape: (3, 2)
5895
+ # # ┌─────┬──────────┐
5896
+ # # │ a ┆ replaced │
5897
+ # # │ --- ┆ --- │
5898
+ # # │ str ┆ str │
5899
+ # # ╞═════╪══════════╡
5900
+ # # │ x ┆ 1 │
5901
+ # # │ y ┆ 2 │
5902
+ # # │ z ┆ 3 │
5903
+ # # └─────┴──────────┘
5904
+ #
5905
+ # @example
5906
+ # df.with_columns(replaced: Polars.col("a").replace(mapping, default: nil))
5907
+ # # =>
5908
+ # # shape: (3, 2)
5909
+ # # ┌─────┬──────────┐
5910
+ # # │ a ┆ replaced │
5911
+ # # │ --- ┆ --- │
5912
+ # # │ str ┆ i64 │
5913
+ # # ╞═════╪══════════╡
5914
+ # # │ x ┆ 1 │
5915
+ # # │ y ┆ 2 │
5916
+ # # │ z ┆ 3 │
5917
+ # # └─────┴──────────┘
5918
+ #
5919
+ # @example Set the `return_dtype` parameter to control the resulting data type directly.
5920
+ # df.with_columns(
5921
+ # replaced: Polars.col("a").replace(mapping, return_dtype: Polars::UInt8)
5922
+ # )
5923
+ # # =>
5924
+ # # shape: (3, 2)
5925
+ # # ┌─────┬──────────┐
5926
+ # # │ a ┆ replaced │
5927
+ # # │ --- ┆ --- │
5928
+ # # │ str ┆ u8 │
5929
+ # # ╞═════╪══════════╡
5930
+ # # │ x ┆ 1 │
5931
+ # # │ y ┆ 2 │
5932
+ # # │ z ┆ 3 │
5933
+ # # └─────┴──────────┘
5934
+ #
5935
+ # @example Expression input is supported for all parameters.
5936
+ # df = Polars::DataFrame.new({"a" => [1, 2, 2, 3], "b" => [1.5, 2.5, 5.0, 1.0]})
5937
+ # df.with_columns(
5938
+ # replaced: Polars.col("a").replace(
5939
+ # Polars.col("a").max,
5940
+ # Polars.col("b").sum,
5941
+ # default: Polars.col("b")
5942
+ # )
5943
+ # )
5944
+ # # =>
5945
+ # # shape: (4, 3)
5946
+ # # ┌─────┬─────┬──────────┐
5947
+ # # │ a ┆ b ┆ replaced │
5948
+ # # │ --- ┆ --- ┆ --- │
5949
+ # # │ i64 ┆ f64 ┆ f64 │
5950
+ # # ╞═════╪═════╪══════════╡
5951
+ # # │ 1 ┆ 1.5 ┆ 1.5 │
5952
+ # # │ 2 ┆ 2.5 ┆ 2.5 │
5953
+ # # │ 2 ┆ 5.0 ┆ 5.0 │
5954
+ # # │ 3 ┆ 1.0 ┆ 10.0 │
5955
+ # # └─────┴─────┴──────────┘
5956
+ def replace(old, new = NO_DEFAULT, default: NO_DEFAULT, return_dtype: nil)
5957
+ if new.eql?(NO_DEFAULT) && old.is_a?(Hash)
5958
+ new = Series.new(old.values)
5959
+ old = Series.new(old.keys)
5960
+ else
5961
+ if old.is_a?(::Array)
5962
+ old = Series.new(old)
5963
+ end
5964
+ if new.is_a?(::Array)
5965
+ new = Series.new(new)
5966
+ end
5967
+ end
5968
+
5969
+ old = Utils.parse_as_expression(old, str_as_lit: true)
5970
+ new = Utils.parse_as_expression(new, str_as_lit: true)
5971
+
5972
+ default =
5973
+ if default.eql?(NO_DEFAULT)
5974
+ nil
5975
+ else
5976
+ Utils.parse_as_expression(default, str_as_lit: true)
5977
+ end
5978
+
5979
+ _from_rbexpr(_rbexpr.replace(old, new, default, return_dtype))
5297
5980
  end
5298
5981
 
5299
5982
  # Create an object namespace of all list related methods.
@@ -5361,7 +6044,7 @@ module Polars
5361
6044
 
5362
6045
  private
5363
6046
 
5364
- def wrap_expr(expr)
6047
+ def _from_rbexpr(expr)
5365
6048
  Utils.wrap_expr(expr)
5366
6049
  end
5367
6050