polars-df 0.8.0-x86_64-linux → 0.9.0-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -1
  3. data/Cargo.lock +107 -59
  4. data/Cargo.toml +0 -3
  5. data/LICENSE-THIRD-PARTY.txt +1726 -754
  6. data/LICENSE.txt +1 -1
  7. data/README.md +2 -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 +449 -0
  12. data/lib/polars/array_name_space.rb +346 -0
  13. data/lib/polars/cat_expr.rb +24 -0
  14. data/lib/polars/cat_name_space.rb +75 -0
  15. data/lib/polars/config.rb +2 -2
  16. data/lib/polars/data_frame.rb +179 -43
  17. data/lib/polars/data_types.rb +191 -28
  18. data/lib/polars/date_time_expr.rb +31 -14
  19. data/lib/polars/exceptions.rb +12 -1
  20. data/lib/polars/expr.rb +866 -186
  21. data/lib/polars/functions/aggregation/horizontal.rb +246 -0
  22. data/lib/polars/functions/aggregation/vertical.rb +282 -0
  23. data/lib/polars/functions/as_datatype.rb +248 -0
  24. data/lib/polars/functions/col.rb +47 -0
  25. data/lib/polars/functions/eager.rb +182 -0
  26. data/lib/polars/functions/lazy.rb +1280 -0
  27. data/lib/polars/functions/len.rb +49 -0
  28. data/lib/polars/functions/lit.rb +35 -0
  29. data/lib/polars/functions/random.rb +16 -0
  30. data/lib/polars/functions/range/date_range.rb +103 -0
  31. data/lib/polars/functions/range/int_range.rb +51 -0
  32. data/lib/polars/functions/repeat.rb +144 -0
  33. data/lib/polars/functions/whenthen.rb +27 -0
  34. data/lib/polars/functions.rb +29 -416
  35. data/lib/polars/group_by.rb +2 -2
  36. data/lib/polars/io.rb +18 -25
  37. data/lib/polars/lazy_frame.rb +367 -53
  38. data/lib/polars/list_expr.rb +152 -6
  39. data/lib/polars/list_name_space.rb +102 -0
  40. data/lib/polars/meta_expr.rb +175 -7
  41. data/lib/polars/series.rb +273 -34
  42. data/lib/polars/string_cache.rb +75 -0
  43. data/lib/polars/string_expr.rb +412 -96
  44. data/lib/polars/string_name_space.rb +4 -4
  45. data/lib/polars/testing.rb +507 -0
  46. data/lib/polars/utils.rb +52 -8
  47. data/lib/polars/version.rb +1 -1
  48. data/lib/polars.rb +15 -2
  49. metadata +33 -4
  50. data/lib/polars/lazy_functions.rb +0 -1181
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.
@@ -1557,7 +1553,7 @@ module Polars
1557
1553
  end
1558
1554
  by = Utils.selection_to_rbexpr_list(by)
1559
1555
 
1560
- wrap_expr(_rbexpr.sort_by(by, reverse))
1556
+ _from_rbexpr(_rbexpr.sort_by(by, reverse))
1561
1557
  end
1562
1558
 
1563
1559
  # Take values by index.
@@ -1598,7 +1594,7 @@ module Polars
1598
1594
  else
1599
1595
  indices_lit = Utils.expr_to_lit_or_expr(indices, str_to_lit: false)
1600
1596
  end
1601
- wrap_expr(_rbexpr.gather(indices_lit._rbexpr))
1597
+ _from_rbexpr(_rbexpr.gather(indices_lit._rbexpr))
1602
1598
  end
1603
1599
  alias_method :take, :gather
1604
1600
 
@@ -1631,7 +1627,7 @@ module Polars
1631
1627
  fill_value = Utils.parse_as_expression(fill_value, str_as_lit: true)
1632
1628
  end
1633
1629
  n = Utils.parse_as_expression(n)
1634
- wrap_expr(_rbexpr.shift(n, fill_value))
1630
+ _from_rbexpr(_rbexpr.shift(n, fill_value))
1635
1631
  end
1636
1632
 
1637
1633
  # Shift the values by a given period and fill the resulting null values.
@@ -1734,9 +1730,9 @@ module Polars
1734
1730
 
1735
1731
  if !value.nil?
1736
1732
  value = Utils.expr_to_lit_or_expr(value, str_to_lit: true)
1737
- wrap_expr(_rbexpr.fill_null(value._rbexpr))
1733
+ _from_rbexpr(_rbexpr.fill_null(value._rbexpr))
1738
1734
  else
1739
- wrap_expr(_rbexpr.fill_null_with_strategy(strategy, limit))
1735
+ _from_rbexpr(_rbexpr.fill_null_with_strategy(strategy, limit))
1740
1736
  end
1741
1737
  end
1742
1738
 
@@ -1765,7 +1761,7 @@ module Polars
1765
1761
  # # └──────┴──────┘
1766
1762
  def fill_nan(fill_value)
1767
1763
  fill_value = Utils.expr_to_lit_or_expr(fill_value, str_to_lit: true)
1768
- wrap_expr(_rbexpr.fill_nan(fill_value._rbexpr))
1764
+ _from_rbexpr(_rbexpr.fill_nan(fill_value._rbexpr))
1769
1765
  end
1770
1766
 
1771
1767
  # Fill missing values with the latest seen values.
@@ -1795,7 +1791,7 @@ module Polars
1795
1791
  # # │ 2 ┆ 6 │
1796
1792
  # # └─────┴─────┘
1797
1793
  def forward_fill(limit: nil)
1798
- wrap_expr(_rbexpr.forward_fill(limit))
1794
+ _from_rbexpr(_rbexpr.forward_fill(limit))
1799
1795
  end
1800
1796
 
1801
1797
  # Fill missing values with the next to be seen values.
@@ -1825,14 +1821,14 @@ module Polars
1825
1821
  # # │ null ┆ 6 │
1826
1822
  # # └──────┴─────┘
1827
1823
  def backward_fill(limit: nil)
1828
- wrap_expr(_rbexpr.backward_fill(limit))
1824
+ _from_rbexpr(_rbexpr.backward_fill(limit))
1829
1825
  end
1830
1826
 
1831
1827
  # Reverse the selection.
1832
1828
  #
1833
1829
  # @return [Expr]
1834
1830
  def reverse
1835
- wrap_expr(_rbexpr.reverse)
1831
+ _from_rbexpr(_rbexpr.reverse)
1836
1832
  end
1837
1833
 
1838
1834
  # Get standard deviation.
@@ -1855,7 +1851,7 @@ module Polars
1855
1851
  # # │ 1.0 │
1856
1852
  # # └─────┘
1857
1853
  def std(ddof: 1)
1858
- wrap_expr(_rbexpr.std(ddof))
1854
+ _from_rbexpr(_rbexpr.std(ddof))
1859
1855
  end
1860
1856
 
1861
1857
  # Get variance.
@@ -1878,7 +1874,7 @@ module Polars
1878
1874
  # # │ 1.0 │
1879
1875
  # # └─────┘
1880
1876
  def var(ddof: 1)
1881
- wrap_expr(_rbexpr.var(ddof))
1877
+ _from_rbexpr(_rbexpr.var(ddof))
1882
1878
  end
1883
1879
 
1884
1880
  # Get maximum value.
@@ -1898,7 +1894,7 @@ module Polars
1898
1894
  # # │ 1.0 │
1899
1895
  # # └─────┘
1900
1896
  def max
1901
- wrap_expr(_rbexpr.max)
1897
+ _from_rbexpr(_rbexpr.max)
1902
1898
  end
1903
1899
 
1904
1900
  # Get minimum value.
@@ -1918,7 +1914,7 @@ module Polars
1918
1914
  # # │ -1.0 │
1919
1915
  # # └──────┘
1920
1916
  def min
1921
- wrap_expr(_rbexpr.min)
1917
+ _from_rbexpr(_rbexpr.min)
1922
1918
  end
1923
1919
 
1924
1920
  # Get maximum value, but propagate/poison encountered NaN values.
@@ -1938,7 +1934,7 @@ module Polars
1938
1934
  # # │ NaN │
1939
1935
  # # └─────┘
1940
1936
  def nan_max
1941
- wrap_expr(_rbexpr.nan_max)
1937
+ _from_rbexpr(_rbexpr.nan_max)
1942
1938
  end
1943
1939
 
1944
1940
  # Get minimum value, but propagate/poison encountered NaN values.
@@ -1958,7 +1954,7 @@ module Polars
1958
1954
  # # │ NaN │
1959
1955
  # # └─────┘
1960
1956
  def nan_min
1961
- wrap_expr(_rbexpr.nan_min)
1957
+ _from_rbexpr(_rbexpr.nan_min)
1962
1958
  end
1963
1959
 
1964
1960
  # Get sum value.
@@ -1982,7 +1978,7 @@ module Polars
1982
1978
  # # │ 0 │
1983
1979
  # # └─────┘
1984
1980
  def sum
1985
- wrap_expr(_rbexpr.sum)
1981
+ _from_rbexpr(_rbexpr.sum)
1986
1982
  end
1987
1983
 
1988
1984
  # Get mean value.
@@ -2002,7 +1998,7 @@ module Polars
2002
1998
  # # │ 0.0 │
2003
1999
  # # └─────┘
2004
2000
  def mean
2005
- wrap_expr(_rbexpr.mean)
2001
+ _from_rbexpr(_rbexpr.mean)
2006
2002
  end
2007
2003
 
2008
2004
  # Get median value using linear interpolation.
@@ -2022,7 +2018,7 @@ module Polars
2022
2018
  # # │ 0.0 │
2023
2019
  # # └─────┘
2024
2020
  def median
2025
- wrap_expr(_rbexpr.median)
2021
+ _from_rbexpr(_rbexpr.median)
2026
2022
  end
2027
2023
 
2028
2024
  # Compute the product of an expression.
@@ -2042,7 +2038,7 @@ module Polars
2042
2038
  # # │ 6 │
2043
2039
  # # └─────┘
2044
2040
  def product
2045
- wrap_expr(_rbexpr.product)
2041
+ _from_rbexpr(_rbexpr.product)
2046
2042
  end
2047
2043
 
2048
2044
  # Count unique values.
@@ -2062,7 +2058,7 @@ module Polars
2062
2058
  # # │ 2 │
2063
2059
  # # └─────┘
2064
2060
  def n_unique
2065
- wrap_expr(_rbexpr.n_unique)
2061
+ _from_rbexpr(_rbexpr.n_unique)
2066
2062
  end
2067
2063
 
2068
2064
  # Approx count unique values.
@@ -2073,7 +2069,7 @@ module Polars
2073
2069
  #
2074
2070
  # @example
2075
2071
  # df = Polars::DataFrame.new({"a" => [1, 1, 2]})
2076
- # df.select(Polars.col("a").approx_unique)
2072
+ # df.select(Polars.col("a").approx_n_unique)
2077
2073
  # # =>
2078
2074
  # # shape: (1, 1)
2079
2075
  # # ┌─────┐
@@ -2083,9 +2079,10 @@ module Polars
2083
2079
  # # ╞═════╡
2084
2080
  # # │ 2 │
2085
2081
  # # └─────┘
2086
- def approx_unique
2087
- wrap_expr(_rbexpr.approx_n_unique)
2082
+ def approx_n_unique
2083
+ _from_rbexpr(_rbexpr.approx_n_unique)
2088
2084
  end
2085
+ alias_method :approx_unique, :approx_n_unique
2089
2086
 
2090
2087
  # Count null values.
2091
2088
  #
@@ -2109,7 +2106,7 @@ module Polars
2109
2106
  # # │ 2 ┆ 0 │
2110
2107
  # # └─────┴─────┘
2111
2108
  def null_count
2112
- wrap_expr(_rbexpr.null_count)
2109
+ _from_rbexpr(_rbexpr.null_count)
2113
2110
  end
2114
2111
 
2115
2112
  # Get index of first unique value.
@@ -2149,7 +2146,7 @@ module Polars
2149
2146
  # # │ 1 │
2150
2147
  # # └─────┘
2151
2148
  def arg_unique
2152
- wrap_expr(_rbexpr.arg_unique)
2149
+ _from_rbexpr(_rbexpr.arg_unique)
2153
2150
  end
2154
2151
 
2155
2152
  # Get unique values of this expression.
@@ -2174,9 +2171,9 @@ module Polars
2174
2171
  # # └─────┘
2175
2172
  def unique(maintain_order: false)
2176
2173
  if maintain_order
2177
- wrap_expr(_rbexpr.unique_stable)
2174
+ _from_rbexpr(_rbexpr.unique_stable)
2178
2175
  else
2179
- wrap_expr(_rbexpr.unique)
2176
+ _from_rbexpr(_rbexpr.unique)
2180
2177
  end
2181
2178
  end
2182
2179
 
@@ -2197,7 +2194,7 @@ module Polars
2197
2194
  # # │ 1 │
2198
2195
  # # └─────┘
2199
2196
  def first
2200
- wrap_expr(_rbexpr.first)
2197
+ _from_rbexpr(_rbexpr.first)
2201
2198
  end
2202
2199
 
2203
2200
  # Get the last value.
@@ -2217,7 +2214,7 @@ module Polars
2217
2214
  # # │ 2 │
2218
2215
  # # └─────┘
2219
2216
  def last
2220
- wrap_expr(_rbexpr.last)
2217
+ _from_rbexpr(_rbexpr.last)
2221
2218
  end
2222
2219
 
2223
2220
  # Apply window function over a subgroup.
@@ -2281,7 +2278,7 @@ module Polars
2281
2278
  # # └────────┘
2282
2279
  def over(expr)
2283
2280
  rbexprs = Utils.selection_to_rbexpr_list(expr)
2284
- wrap_expr(_rbexpr.over(rbexprs))
2281
+ _from_rbexpr(_rbexpr.over(rbexprs))
2285
2282
  end
2286
2283
 
2287
2284
  # Get mask of unique values.
@@ -2303,7 +2300,7 @@ module Polars
2303
2300
  # # │ true │
2304
2301
  # # └───────┘
2305
2302
  def is_unique
2306
- wrap_expr(_rbexpr.is_unique)
2303
+ _from_rbexpr(_rbexpr.is_unique)
2307
2304
  end
2308
2305
 
2309
2306
  # Get a mask of the first unique value.
@@ -2331,7 +2328,7 @@ module Polars
2331
2328
  # # │ 5 ┆ true │
2332
2329
  # # └─────┴──────────┘
2333
2330
  def is_first_distinct
2334
- wrap_expr(_rbexpr.is_first_distinct)
2331
+ _from_rbexpr(_rbexpr.is_first_distinct)
2335
2332
  end
2336
2333
  alias_method :is_first, :is_first_distinct
2337
2334
 
@@ -2354,7 +2351,7 @@ module Polars
2354
2351
  # # │ false │
2355
2352
  # # └───────┘
2356
2353
  def is_duplicated
2357
- wrap_expr(_rbexpr.is_duplicated)
2354
+ _from_rbexpr(_rbexpr.is_duplicated)
2358
2355
  end
2359
2356
 
2360
2357
  # Get a boolean mask of the local maximum peaks.
@@ -2378,7 +2375,7 @@ module Polars
2378
2375
  # # │ true │
2379
2376
  # # └───────┘
2380
2377
  def peak_max
2381
- wrap_expr(_rbexpr.peak_max)
2378
+ _from_rbexpr(_rbexpr.peak_max)
2382
2379
  end
2383
2380
 
2384
2381
  # Get a boolean mask of the local minimum peaks.
@@ -2402,7 +2399,7 @@ module Polars
2402
2399
  # # │ false │
2403
2400
  # # └───────┘
2404
2401
  def peak_min
2405
- wrap_expr(_rbexpr.peak_min)
2402
+ _from_rbexpr(_rbexpr.peak_min)
2406
2403
  end
2407
2404
 
2408
2405
  # Get quantile value.
@@ -2476,7 +2473,7 @@ module Polars
2476
2473
  # # └─────┘
2477
2474
  def quantile(quantile, interpolation: "nearest")
2478
2475
  quantile = Utils.expr_to_lit_or_expr(quantile, str_to_lit: false)
2479
- wrap_expr(_rbexpr.quantile(quantile._rbexpr, interpolation))
2476
+ _from_rbexpr(_rbexpr.quantile(quantile._rbexpr, interpolation))
2480
2477
  end
2481
2478
 
2482
2479
  # Bin continuous values into discrete categories.
@@ -2532,7 +2529,7 @@ module Polars
2532
2529
  # # │ 2 ┆ inf ┆ (1, inf] │
2533
2530
  # # └─────┴──────┴────────────┘
2534
2531
  def cut(breaks, labels: nil, left_closed: false, include_breaks: false)
2535
- wrap_expr(_rbexpr.cut(breaks, labels, left_closed, include_breaks))
2532
+ _from_rbexpr(_rbexpr.cut(breaks, labels, left_closed, include_breaks))
2536
2533
  end
2537
2534
 
2538
2535
  # Bin continuous values into discrete categories based on their quantiles.
@@ -2623,7 +2620,7 @@ module Polars
2623
2620
  )
2624
2621
  end
2625
2622
 
2626
- wrap_expr(rbexpr)
2623
+ _from_rbexpr(rbexpr)
2627
2624
  end
2628
2625
 
2629
2626
  # Get the lengths of runs of identical values.
@@ -2648,7 +2645,7 @@ module Polars
2648
2645
  # # │ 2 ┆ 3 │
2649
2646
  # # └─────────┴────────┘
2650
2647
  def rle
2651
- wrap_expr(_rbexpr.rle)
2648
+ _from_rbexpr(_rbexpr.rle)
2652
2649
  end
2653
2650
 
2654
2651
  # Map values to run IDs.
@@ -2676,7 +2673,7 @@ module Polars
2676
2673
  # # │ 1 ┆ y ┆ 2 ┆ 3 │
2677
2674
  # # └─────┴──────┴─────┴──────┘
2678
2675
  def rle_id
2679
- wrap_expr(_rbexpr.rle_id)
2676
+ _from_rbexpr(_rbexpr.rle_id)
2680
2677
  end
2681
2678
 
2682
2679
  # Filter a single column.
@@ -2715,7 +2712,7 @@ module Polars
2715
2712
  # # │ g2 ┆ 0 ┆ 3 │
2716
2713
  # # └───────────┴─────┴─────┘
2717
2714
  def filter(predicate)
2718
- wrap_expr(_rbexpr.filter(predicate._rbexpr))
2715
+ _from_rbexpr(_rbexpr.filter(predicate._rbexpr))
2719
2716
  end
2720
2717
 
2721
2718
  # Filter a single column.
@@ -2793,7 +2790,7 @@ module Polars
2793
2790
  # if !return_dtype.nil?
2794
2791
  # return_dtype = Utils.rb_type_to_dtype(return_dtype)
2795
2792
  # end
2796
- # wrap_expr(_rbexpr.map(f, return_dtype, agg_list))
2793
+ # _from_rbexpr(_rbexpr.map(f, return_dtype, agg_list))
2797
2794
  # end
2798
2795
 
2799
2796
  # Apply a custom/user-defined function (UDF) in a GroupBy or Projection context.
@@ -2904,7 +2901,7 @@ module Polars
2904
2901
  # # │ b ┆ [2, 3, 4] │
2905
2902
  # # └───────┴───────────┘
2906
2903
  def flatten
2907
- wrap_expr(_rbexpr.explode)
2904
+ _from_rbexpr(_rbexpr.explode)
2908
2905
  end
2909
2906
 
2910
2907
  # Explode a list or utf8 Series.
@@ -2931,7 +2928,7 @@ module Polars
2931
2928
  # # │ 6 │
2932
2929
  # # └─────┘
2933
2930
  def explode
2934
- wrap_expr(_rbexpr.explode)
2931
+ _from_rbexpr(_rbexpr.explode)
2935
2932
  end
2936
2933
 
2937
2934
  # Take every nth value in the Series and return as a new Series.
@@ -2953,7 +2950,7 @@ module Polars
2953
2950
  # # │ 7 │
2954
2951
  # # └─────┘
2955
2952
  def gather_every(n, offset = 0)
2956
- wrap_expr(_rbexpr.gather_every(n, offset))
2953
+ _from_rbexpr(_rbexpr.gather_every(n, offset))
2957
2954
  end
2958
2955
  alias_method :take_every, :gather_every
2959
2956
 
@@ -2979,7 +2976,7 @@ module Polars
2979
2976
  # # │ 3 │
2980
2977
  # # └─────┘
2981
2978
  def head(n = 10)
2982
- wrap_expr(_rbexpr.head(n))
2979
+ _from_rbexpr(_rbexpr.head(n))
2983
2980
  end
2984
2981
 
2985
2982
  # Get the last `n` rows.
@@ -3004,7 +3001,7 @@ module Polars
3004
3001
  # # │ 7 │
3005
3002
  # # └─────┘
3006
3003
  def tail(n = 10)
3007
- wrap_expr(_rbexpr.tail(n))
3004
+ _from_rbexpr(_rbexpr.tail(n))
3008
3005
  end
3009
3006
 
3010
3007
  # Get the first `n` rows.
@@ -3019,6 +3016,500 @@ module Polars
3019
3016
  head(n)
3020
3017
  end
3021
3018
 
3019
+ # Method equivalent of equality operator `expr == other`.
3020
+ #
3021
+ # @param other [Object]
3022
+ # A literal or expression value to compare with.
3023
+ #
3024
+ # @return [Expr]
3025
+ # @example
3026
+ # df = Polars::DataFrame.new(
3027
+ # {
3028
+ # "x" => [1.0, 2.0, Float::NAN, 4.0],
3029
+ # "y" => [2.0, 2.0, Float::NAN, 4.0]
3030
+ # }
3031
+ # )
3032
+ # df.with_columns(
3033
+ # Polars.col("x").eq(Polars.col("y")).alias("x == y")
3034
+ # )
3035
+ # # =>
3036
+ # # shape: (4, 3)
3037
+ # # ┌─────┬─────┬────────┐
3038
+ # # │ x ┆ y ┆ x == y │
3039
+ # # │ --- ┆ --- ┆ --- │
3040
+ # # │ f64 ┆ f64 ┆ bool │
3041
+ # # ╞═════╪═════╪════════╡
3042
+ # # │ 1.0 ┆ 2.0 ┆ false │
3043
+ # # │ 2.0 ┆ 2.0 ┆ true │
3044
+ # # │ NaN ┆ NaN ┆ true │
3045
+ # # │ 4.0 ┆ 4.0 ┆ true │
3046
+ # # └─────┴─────┴────────┘
3047
+ def eq(other)
3048
+ self == other
3049
+ end
3050
+
3051
+ # Method equivalent of equality operator `expr == other` where `None == None`.
3052
+ #
3053
+ # This differs from default `eq` where null values are propagated.
3054
+ #
3055
+ # @param other [Object]
3056
+ # A literal or expression value to compare with.
3057
+ #
3058
+ # @return [Expr]
3059
+ #
3060
+ # @example
3061
+ # df = Polars::DataFrame.new(
3062
+ # data={
3063
+ # "x" => [1.0, 2.0, Float::NAN, 4.0, nil, nil],
3064
+ # "y" => [2.0, 2.0, Float::NAN, 4.0, 5.0, nil]
3065
+ # }
3066
+ # )
3067
+ # df.with_columns(
3068
+ # Polars.col("x").eq(Polars.col("y")).alias("x eq y"),
3069
+ # Polars.col("x").eq_missing(Polars.col("y")).alias("x eq_missing y")
3070
+ # )
3071
+ # # =>
3072
+ # # shape: (6, 4)
3073
+ # # ┌──────┬──────┬────────┬────────────────┐
3074
+ # # │ x ┆ y ┆ x eq y ┆ x eq_missing y │
3075
+ # # │ --- ┆ --- ┆ --- ┆ --- │
3076
+ # # │ f64 ┆ f64 ┆ bool ┆ bool │
3077
+ # # ╞══════╪══════╪════════╪════════════════╡
3078
+ # # │ 1.0 ┆ 2.0 ┆ false ┆ false │
3079
+ # # │ 2.0 ┆ 2.0 ┆ true ┆ true │
3080
+ # # │ NaN ┆ NaN ┆ true ┆ true │
3081
+ # # │ 4.0 ┆ 4.0 ┆ true ┆ true │
3082
+ # # │ null ┆ 5.0 ┆ null ┆ false │
3083
+ # # │ null ┆ null ┆ null ┆ true │
3084
+ # # └──────┴──────┴────────┴────────────────┘
3085
+ def eq_missing(other)
3086
+ other = Utils.parse_as_expression(other, str_as_lit: true)
3087
+ _from_rbexpr(_rbexpr.eq_missing(other))
3088
+ end
3089
+
3090
+ # Method equivalent of "greater than or equal" operator `expr >= other`.
3091
+ #
3092
+ # @param other [Object]
3093
+ # A literal or expression value to compare with.
3094
+ #
3095
+ # @return [Expr]
3096
+ #
3097
+ # @example
3098
+ # df = Polars::DataFrame.new(
3099
+ # {
3100
+ # "x" => [5.0, 4.0, Float::NAN, 2.0],
3101
+ # "y" => [5.0, 3.0, Float::NAN, 1.0]
3102
+ # }
3103
+ # )
3104
+ # df.with_columns(
3105
+ # Polars.col("x").ge(Polars.col("y")).alias("x >= y")
3106
+ # )
3107
+ # # =>
3108
+ # # shape: (4, 3)
3109
+ # # ┌─────┬─────┬────────┐
3110
+ # # │ x ┆ y ┆ x >= y │
3111
+ # # │ --- ┆ --- ┆ --- │
3112
+ # # │ f64 ┆ f64 ┆ bool │
3113
+ # # ╞═════╪═════╪════════╡
3114
+ # # │ 5.0 ┆ 5.0 ┆ true │
3115
+ # # │ 4.0 ┆ 3.0 ┆ true │
3116
+ # # │ NaN ┆ NaN ┆ true │
3117
+ # # │ 2.0 ┆ 1.0 ┆ true │
3118
+ # # └─────┴─────┴────────┘
3119
+ def ge(other)
3120
+ self >= other
3121
+ end
3122
+
3123
+ # Method equivalent of "greater than" operator `expr > other`.
3124
+ #
3125
+ # @param other [Object]
3126
+ # A literal or expression value to compare with.
3127
+ #
3128
+ # @return [Expr]
3129
+ #
3130
+ # @example
3131
+ # df = Polars::DataFrame.new(
3132
+ # {
3133
+ # "x" => [5.0, 4.0, Float::NAN, 2.0],
3134
+ # "y" => [5.0, 3.0, Float::NAN, 1.0]
3135
+ # }
3136
+ # )
3137
+ # df.with_columns(
3138
+ # Polars.col("x").gt(Polars.col("y")).alias("x > y")
3139
+ # )
3140
+ # # =>
3141
+ # # shape: (4, 3)
3142
+ # # ┌─────┬─────┬───────┐
3143
+ # # │ x ┆ y ┆ x > y │
3144
+ # # │ --- ┆ --- ┆ --- │
3145
+ # # │ f64 ┆ f64 ┆ bool │
3146
+ # # ╞═════╪═════╪═══════╡
3147
+ # # │ 5.0 ┆ 5.0 ┆ false │
3148
+ # # │ 4.0 ┆ 3.0 ┆ true │
3149
+ # # │ NaN ┆ NaN ┆ false │
3150
+ # # │ 2.0 ┆ 1.0 ┆ true │
3151
+ # # └─────┴─────┴───────┘
3152
+ def gt(other)
3153
+ self > other
3154
+ end
3155
+
3156
+ # Method equivalent of "less than or equal" operator `expr <= other`.
3157
+ #
3158
+ # @param other [Object]
3159
+ # A literal or expression value to compare with.
3160
+ #
3161
+ # @return [Expr]
3162
+ #
3163
+ # @example
3164
+ # df = Polars::DataFrame.new(
3165
+ # {
3166
+ # "x" => [5.0, 4.0, Float::NAN, 0.5],
3167
+ # "y" => [5.0, 3.5, Float::NAN, 2.0]
3168
+ # }
3169
+ # )
3170
+ # df.with_columns(
3171
+ # Polars.col("x").le(Polars.col("y")).alias("x <= y")
3172
+ # )
3173
+ # # =>
3174
+ # # shape: (4, 3)
3175
+ # # ┌─────┬─────┬────────┐
3176
+ # # │ x ┆ y ┆ x <= y │
3177
+ # # │ --- ┆ --- ┆ --- │
3178
+ # # │ f64 ┆ f64 ┆ bool │
3179
+ # # ╞═════╪═════╪════════╡
3180
+ # # │ 5.0 ┆ 5.0 ┆ true │
3181
+ # # │ 4.0 ┆ 3.5 ┆ false │
3182
+ # # │ NaN ┆ NaN ┆ true │
3183
+ # # │ 0.5 ┆ 2.0 ┆ true │
3184
+ # # └─────┴─────┴────────┘
3185
+ def le(other)
3186
+ self <= other
3187
+ end
3188
+
3189
+ # Method equivalent of "less than" operator `expr < other`.
3190
+ #
3191
+ # @param other [Object]
3192
+ # A literal or expression value to compare with.
3193
+ #
3194
+ # @return [Expr]
3195
+ #
3196
+ # @example
3197
+ # df = Polars::DataFrame.new(
3198
+ # {
3199
+ # "x" => [1.0, 2.0, Float::NAN, 3.0],
3200
+ # "y" => [2.0, 2.0, Float::NAN, 4.0]
3201
+ # }
3202
+ # )
3203
+ # df.with_columns(
3204
+ # Polars.col("x").lt(Polars.col("y")).alias("x < y"),
3205
+ # )
3206
+ # # =>
3207
+ # # shape: (4, 3)
3208
+ # # ┌─────┬─────┬───────┐
3209
+ # # │ x ┆ y ┆ x < y │
3210
+ # # │ --- ┆ --- ┆ --- │
3211
+ # # │ f64 ┆ f64 ┆ bool │
3212
+ # # ╞═════╪═════╪═══════╡
3213
+ # # │ 1.0 ┆ 2.0 ┆ true │
3214
+ # # │ 2.0 ┆ 2.0 ┆ false │
3215
+ # # │ NaN ┆ NaN ┆ false │
3216
+ # # │ 3.0 ┆ 4.0 ┆ true │
3217
+ # # └─────┴─────┴───────┘
3218
+ def lt(other)
3219
+ self < other
3220
+ end
3221
+
3222
+ # Method equivalent of inequality operator `expr != other`.
3223
+ #
3224
+ # @param other [Object]
3225
+ # A literal or expression value to compare with.
3226
+ #
3227
+ # @return [Expr]
3228
+ #
3229
+ # @example
3230
+ # df = Polars::DataFrame.new(
3231
+ # {
3232
+ # "x" => [1.0, 2.0, Float::NAN, 4.0],
3233
+ # "y" => [2.0, 2.0, Float::NAN, 4.0]
3234
+ # }
3235
+ # )
3236
+ # df.with_columns(
3237
+ # Polars.col("x").ne(Polars.col("y")).alias("x != y"),
3238
+ # )
3239
+ # # =>
3240
+ # # shape: (4, 3)
3241
+ # # ┌─────┬─────┬────────┐
3242
+ # # │ x ┆ y ┆ x != y │
3243
+ # # │ --- ┆ --- ┆ --- │
3244
+ # # │ f64 ┆ f64 ┆ bool │
3245
+ # # ╞═════╪═════╪════════╡
3246
+ # # │ 1.0 ┆ 2.0 ┆ true │
3247
+ # # │ 2.0 ┆ 2.0 ┆ false │
3248
+ # # │ NaN ┆ NaN ┆ false │
3249
+ # # │ 4.0 ┆ 4.0 ┆ false │
3250
+ # # └─────┴─────┴────────┘
3251
+ def ne(other)
3252
+ self != other
3253
+ end
3254
+
3255
+ # Method equivalent of equality operator `expr != other` where `None == None`.
3256
+ #
3257
+ # This differs from default `ne` where null values are propagated.
3258
+ #
3259
+ # @param other [Object]
3260
+ # A literal or expression value to compare with.
3261
+ #
3262
+ # @return [Expr]
3263
+ #
3264
+ # @example
3265
+ # df = Polars::DataFrame.new(
3266
+ # {
3267
+ # "x" => [1.0, 2.0, Float::NAN, 4.0, nil, nil],
3268
+ # "y" => [2.0, 2.0, Float::NAN, 4.0, 5.0, nil]
3269
+ # }
3270
+ # )
3271
+ # df.with_columns(
3272
+ # Polars.col("x").ne(Polars.col("y")).alias("x ne y"),
3273
+ # Polars.col("x").ne_missing(Polars.col("y")).alias("x ne_missing y")
3274
+ # )
3275
+ # # =>
3276
+ # # shape: (6, 4)
3277
+ # # ┌──────┬──────┬────────┬────────────────┐
3278
+ # # │ x ┆ y ┆ x ne y ┆ x ne_missing y │
3279
+ # # │ --- ┆ --- ┆ --- ┆ --- │
3280
+ # # │ f64 ┆ f64 ┆ bool ┆ bool │
3281
+ # # ╞══════╪══════╪════════╪════════════════╡
3282
+ # # │ 1.0 ┆ 2.0 ┆ true ┆ true │
3283
+ # # │ 2.0 ┆ 2.0 ┆ false ┆ false │
3284
+ # # │ NaN ┆ NaN ┆ false ┆ false │
3285
+ # # │ 4.0 ┆ 4.0 ┆ false ┆ false │
3286
+ # # │ null ┆ 5.0 ┆ null ┆ true │
3287
+ # # │ null ┆ null ┆ null ┆ false │
3288
+ # # └──────┴──────┴────────┴────────────────┘
3289
+ def ne_missing(other)
3290
+ other = Utils.parse_as_expression(other, str_as_lit: true)
3291
+ _from_rbexpr(_rbexpr.neq_missing(other))
3292
+ end
3293
+
3294
+ # Method equivalent of addition operator `expr + other`.
3295
+ #
3296
+ # @param other [Object]
3297
+ # numeric or string value; accepts expression input.
3298
+ #
3299
+ # @return [Expr]
3300
+ #
3301
+ # @example
3302
+ # df = Polars::DataFrame.new({"x" => [1, 2, 3, 4, 5]})
3303
+ # df.with_columns(
3304
+ # Polars.col("x").add(2).alias("x+int"),
3305
+ # Polars.col("x").add(Polars.col("x").cum_prod).alias("x+expr")
3306
+ # )
3307
+ # # =>
3308
+ # # shape: (5, 3)
3309
+ # # ┌─────┬───────┬────────┐
3310
+ # # │ x ┆ x+int ┆ x+expr │
3311
+ # # │ --- ┆ --- ┆ --- │
3312
+ # # │ i64 ┆ i64 ┆ i64 │
3313
+ # # ╞═════╪═══════╪════════╡
3314
+ # # │ 1 ┆ 3 ┆ 2 │
3315
+ # # │ 2 ┆ 4 ┆ 4 │
3316
+ # # │ 3 ┆ 5 ┆ 9 │
3317
+ # # │ 4 ┆ 6 ┆ 28 │
3318
+ # # │ 5 ┆ 7 ┆ 125 │
3319
+ # # └─────┴───────┴────────┘
3320
+ #
3321
+ # @example
3322
+ # df = Polars::DataFrame.new(
3323
+ # {"x" => ["a", "d", "g"], "y": ["b", "e", "h"], "z": ["c", "f", "i"]}
3324
+ # )
3325
+ # df.with_columns(Polars.col("x").add(Polars.col("y")).add(Polars.col("z")).alias("xyz"))
3326
+ # # =>
3327
+ # # shape: (3, 4)
3328
+ # # ┌─────┬─────┬─────┬─────┐
3329
+ # # │ x ┆ y ┆ z ┆ xyz │
3330
+ # # │ --- ┆ --- ┆ --- ┆ --- │
3331
+ # # │ str ┆ str ┆ str ┆ str │
3332
+ # # ╞═════╪═════╪═════╪═════╡
3333
+ # # │ a ┆ b ┆ c ┆ abc │
3334
+ # # │ d ┆ e ┆ f ┆ def │
3335
+ # # │ g ┆ h ┆ i ┆ ghi │
3336
+ # # └─────┴─────┴─────┴─────┘
3337
+ def add(other)
3338
+ self + other
3339
+ end
3340
+
3341
+ # Method equivalent of integer division operator `expr // other`.
3342
+ #
3343
+ # @param other [Object]
3344
+ # Numeric literal or expression value.
3345
+ #
3346
+ # @return [Expr]
3347
+ #
3348
+ # @example
3349
+ # df = Polars::DataFrame.new({"x" => [1, 2, 3, 4, 5]})
3350
+ # df.with_columns(
3351
+ # Polars.col("x").truediv(2).alias("x/2"),
3352
+ # Polars.col("x").floordiv(2).alias("x//2")
3353
+ # )
3354
+ # # =>
3355
+ # # shape: (5, 3)
3356
+ # # ┌─────┬─────┬──────┐
3357
+ # # │ x ┆ x/2 ┆ x//2 │
3358
+ # # │ --- ┆ --- ┆ --- │
3359
+ # # │ i64 ┆ f64 ┆ i64 │
3360
+ # # ╞═════╪═════╪══════╡
3361
+ # # │ 1 ┆ 0.5 ┆ 0 │
3362
+ # # │ 2 ┆ 1.0 ┆ 1 │
3363
+ # # │ 3 ┆ 1.5 ┆ 1 │
3364
+ # # │ 4 ┆ 2.0 ┆ 2 │
3365
+ # # │ 5 ┆ 2.5 ┆ 2 │
3366
+ # # └─────┴─────┴──────┘
3367
+ def floordiv(other)
3368
+ _from_rbexpr(_rbexpr.floordiv(_to_rbexpr(other)))
3369
+ end
3370
+
3371
+ # Method equivalent of modulus operator `expr % other`.
3372
+ #
3373
+ # @param other [Object]
3374
+ # Numeric literal or expression value.
3375
+ #
3376
+ # @return [Expr]
3377
+ #
3378
+ # @example
3379
+ # df = Polars::DataFrame.new({"x" => [0, 1, 2, 3, 4]})
3380
+ # df.with_columns(Polars.col("x").mod(2).alias("x%2"))
3381
+ # # =>
3382
+ # # shape: (5, 2)
3383
+ # # ┌─────┬─────┐
3384
+ # # │ x ┆ x%2 │
3385
+ # # │ --- ┆ --- │
3386
+ # # │ i64 ┆ i64 │
3387
+ # # ╞═════╪═════╡
3388
+ # # │ 0 ┆ 0 │
3389
+ # # │ 1 ┆ 1 │
3390
+ # # │ 2 ┆ 0 │
3391
+ # # │ 3 ┆ 1 │
3392
+ # # │ 4 ┆ 0 │
3393
+ # # └─────┴─────┘
3394
+ def mod(other)
3395
+ self % other
3396
+ end
3397
+
3398
+ # Method equivalent of multiplication operator `expr * other`.
3399
+ #
3400
+ # @param other [Object]
3401
+ # Numeric literal or expression value.
3402
+ #
3403
+ # @return [Expr]
3404
+ #
3405
+ # @example
3406
+ # df = Polars::DataFrame.new({"x" => [1, 2, 4, 8, 16]})
3407
+ # df.with_columns(
3408
+ # Polars.col("x").mul(2).alias("x*2"),
3409
+ # Polars.col("x").mul(Polars.col("x").log(2)).alias("x * xlog2"),
3410
+ # )
3411
+ # # =>
3412
+ # # shape: (5, 3)
3413
+ # # ┌─────┬─────┬───────────┐
3414
+ # # │ x ┆ x*2 ┆ x * xlog2 │
3415
+ # # │ --- ┆ --- ┆ --- │
3416
+ # # │ i64 ┆ i64 ┆ f64 │
3417
+ # # ╞═════╪═════╪═══════════╡
3418
+ # # │ 1 ┆ 2 ┆ 0.0 │
3419
+ # # │ 2 ┆ 4 ┆ 2.0 │
3420
+ # # │ 4 ┆ 8 ┆ 8.0 │
3421
+ # # │ 8 ┆ 16 ┆ 24.0 │
3422
+ # # │ 16 ┆ 32 ┆ 64.0 │
3423
+ # # └─────┴─────┴───────────┘
3424
+ def mul(other)
3425
+ self * other
3426
+ end
3427
+
3428
+ # Method equivalent of subtraction operator `expr - other`.
3429
+ #
3430
+ # @param other [Object]
3431
+ # Numeric literal or expression value.
3432
+ #
3433
+ # @return [Expr]
3434
+ #
3435
+ # @example
3436
+ # df = Polars::DataFrame.new({"x" => [0, 1, 2, 3, 4]})
3437
+ # df.with_columns(
3438
+ # Polars.col("x").sub(2).alias("x-2"),
3439
+ # Polars.col("x").sub(Polars.col("x").cum_sum).alias("x-expr"),
3440
+ # )
3441
+ # # =>
3442
+ # # shape: (5, 3)
3443
+ # # ┌─────┬─────┬────────┐
3444
+ # # │ x ┆ x-2 ┆ x-expr │
3445
+ # # │ --- ┆ --- ┆ --- │
3446
+ # # │ i64 ┆ i64 ┆ i64 │
3447
+ # # ╞═════╪═════╪════════╡
3448
+ # # │ 0 ┆ -2 ┆ 0 │
3449
+ # # │ 1 ┆ -1 ┆ 0 │
3450
+ # # │ 2 ┆ 0 ┆ -1 │
3451
+ # # │ 3 ┆ 1 ┆ -3 │
3452
+ # # │ 4 ┆ 2 ┆ -6 │
3453
+ # # └─────┴─────┴────────┘
3454
+ def sub(other)
3455
+ self - other
3456
+ end
3457
+
3458
+ # Method equivalent of unary minus operator `-expr`.
3459
+ #
3460
+ # @return [Expr]
3461
+ #
3462
+ # @example
3463
+ # df = Polars::DataFrame.new({"a" => [-1, 0, 2, nil]})
3464
+ # df.with_columns(Polars.col("a").neg)
3465
+ # # =>
3466
+ # # shape: (4, 1)
3467
+ # # ┌──────┐
3468
+ # # │ a │
3469
+ # # │ --- │
3470
+ # # │ i64 │
3471
+ # # ╞══════╡
3472
+ # # │ 1 │
3473
+ # # │ 0 │
3474
+ # # │ -2 │
3475
+ # # │ null │
3476
+ # # └──────┘
3477
+ def neg
3478
+ -self
3479
+ end
3480
+
3481
+ # Method equivalent of float division operator `expr / other`.
3482
+ #
3483
+ # @param other [Object]
3484
+ # Numeric literal or expression value.
3485
+ #
3486
+ # @return [Expr]
3487
+ #
3488
+ # @example
3489
+ # df = Polars::DataFrame.new(
3490
+ # {"x" => [-2, -1, 0, 1, 2], "y" => [0.5, 0.0, 0.0, -4.0, -0.5]}
3491
+ # )
3492
+ # df.with_columns(
3493
+ # Polars.col("x").truediv(2).alias("x/2"),
3494
+ # Polars.col("x").truediv(Polars.col("y")).alias("x/y")
3495
+ # )
3496
+ # # =>
3497
+ # # shape: (5, 4)
3498
+ # # ┌─────┬──────┬──────┬───────┐
3499
+ # # │ x ┆ y ┆ x/2 ┆ x/y │
3500
+ # # │ --- ┆ --- ┆ --- ┆ --- │
3501
+ # # │ i64 ┆ f64 ┆ f64 ┆ f64 │
3502
+ # # ╞═════╪══════╪══════╪═══════╡
3503
+ # # │ -2 ┆ 0.5 ┆ -1.0 ┆ -4.0 │
3504
+ # # │ -1 ┆ 0.0 ┆ -0.5 ┆ -inf │
3505
+ # # │ 0 ┆ 0.0 ┆ 0.0 ┆ NaN │
3506
+ # # │ 1 ┆ -4.0 ┆ 0.5 ┆ -0.25 │
3507
+ # # │ 2 ┆ -0.5 ┆ 1.0 ┆ -4.0 │
3508
+ # # └─────┴──────┴──────┴───────┘
3509
+ def truediv(other)
3510
+ self / other
3511
+ end
3512
+
3022
3513
  # Raise expression to the power of exponent.
3023
3514
  #
3024
3515
  # @return [Expr]
@@ -3039,8 +3530,35 @@ module Polars
3039
3530
  # # │ 64.0 │
3040
3531
  # # └──────┘
3041
3532
  def pow(exponent)
3042
- exponent = Utils.expr_to_lit_or_expr(exponent)
3043
- wrap_expr(_rbexpr.pow(exponent._rbexpr))
3533
+ self**exponent
3534
+ end
3535
+
3536
+ # Method equivalent of bitwise exclusive-or operator `expr ^ other`.
3537
+ #
3538
+ # @param other [Object]
3539
+ # Integer or boolean value; accepts expression input.
3540
+ #
3541
+ # @return [Expr]
3542
+ #
3543
+ # @example
3544
+ # df = Polars::DataFrame.new(
3545
+ # {"x" => [true, false, true, false], "y" => [true, true, false, false]}
3546
+ # )
3547
+ # df.with_columns(Polars.col("x").xor(Polars.col("y")).alias("x ^ y"))
3548
+ # # =>
3549
+ # # shape: (4, 3)
3550
+ # # ┌───────┬───────┬───────┐
3551
+ # # │ x ┆ y ┆ x ^ y │
3552
+ # # │ --- ┆ --- ┆ --- │
3553
+ # # │ bool ┆ bool ┆ bool │
3554
+ # # ╞═══════╪═══════╪═══════╡
3555
+ # # │ true ┆ true ┆ false │
3556
+ # # │ false ┆ true ┆ true │
3557
+ # # │ true ┆ false ┆ true │
3558
+ # # │ false ┆ false ┆ false │
3559
+ # # └───────┴───────┴───────┘
3560
+ def xor(other)
3561
+ self ^ other
3044
3562
  end
3045
3563
 
3046
3564
  # Check if elements of this expression are present in the other Series.
@@ -3076,7 +3594,7 @@ module Polars
3076
3594
  else
3077
3595
  other = Utils.expr_to_lit_or_expr(other, str_to_lit: false)
3078
3596
  end
3079
- wrap_expr(_rbexpr.is_in(other._rbexpr))
3597
+ _from_rbexpr(_rbexpr.is_in(other._rbexpr))
3080
3598
  end
3081
3599
  alias_method :in?, :is_in
3082
3600
 
@@ -3112,7 +3630,7 @@ module Polars
3112
3630
  # # └─────────────────┘
3113
3631
  def repeat_by(by)
3114
3632
  by = Utils.expr_to_lit_or_expr(by, str_to_lit: false)
3115
- wrap_expr(_rbexpr.repeat_by(by._rbexpr))
3633
+ _from_rbexpr(_rbexpr.repeat_by(by._rbexpr))
3116
3634
  end
3117
3635
 
3118
3636
  # Check if this expression is between start and end.
@@ -3238,7 +3756,7 @@ module Polars
3238
3756
  k1 = seed_1.nil? ? seed : seed_1
3239
3757
  k2 = seed_2.nil? ? seed : seed_2
3240
3758
  k3 = seed_3.nil? ? seed : seed_3
3241
- wrap_expr(_rbexpr._hash(k0, k1, k2, k3))
3759
+ _from_rbexpr(_rbexpr._hash(k0, k1, k2, k3))
3242
3760
  end
3243
3761
 
3244
3762
  # Reinterpret the underlying bits as a signed/unsigned integer.
@@ -3272,7 +3790,7 @@ module Polars
3272
3790
  # # │ 2 ┆ 2 │
3273
3791
  # # └───────────────┴──────────┘
3274
3792
  def reinterpret(signed: false)
3275
- wrap_expr(_rbexpr.reinterpret(signed))
3793
+ _from_rbexpr(_rbexpr.reinterpret(signed))
3276
3794
  end
3277
3795
 
3278
3796
  # Print the value that this expression evaluates to and pass on the value.
@@ -3335,7 +3853,7 @@ module Polars
3335
3853
  # # │ 3.0 ┆ 3.0 │
3336
3854
  # # └─────┴─────┘
3337
3855
  def interpolate(method: "linear")
3338
- wrap_expr(_rbexpr.interpolate(method))
3856
+ _from_rbexpr(_rbexpr.interpolate(method))
3339
3857
  end
3340
3858
 
3341
3859
  # Apply a rolling min (moving min) over the values in this array.
@@ -3420,7 +3938,7 @@ module Polars
3420
3938
  window_size, min_periods = _prepare_rolling_window_args(
3421
3939
  window_size, min_periods
3422
3940
  )
3423
- wrap_expr(
3941
+ _from_rbexpr(
3424
3942
  _rbexpr.rolling_min(
3425
3943
  window_size, weights, min_periods, center, by, closed
3426
3944
  )
@@ -3509,7 +4027,7 @@ module Polars
3509
4027
  window_size, min_periods = _prepare_rolling_window_args(
3510
4028
  window_size, min_periods
3511
4029
  )
3512
- wrap_expr(
4030
+ _from_rbexpr(
3513
4031
  _rbexpr.rolling_max(
3514
4032
  window_size, weights, min_periods, center, by, closed
3515
4033
  )
@@ -3598,7 +4116,7 @@ module Polars
3598
4116
  window_size, min_periods = _prepare_rolling_window_args(
3599
4117
  window_size, min_periods
3600
4118
  )
3601
- wrap_expr(
4119
+ _from_rbexpr(
3602
4120
  _rbexpr.rolling_mean(
3603
4121
  window_size, weights, min_periods, center, by, closed
3604
4122
  )
@@ -3687,7 +4205,7 @@ module Polars
3687
4205
  window_size, min_periods = _prepare_rolling_window_args(
3688
4206
  window_size, min_periods
3689
4207
  )
3690
- wrap_expr(
4208
+ _from_rbexpr(
3691
4209
  _rbexpr.rolling_sum(
3692
4210
  window_size, weights, min_periods, center, by, closed
3693
4211
  )
@@ -3778,7 +4296,7 @@ module Polars
3778
4296
  window_size, min_periods = _prepare_rolling_window_args(
3779
4297
  window_size, min_periods
3780
4298
  )
3781
- wrap_expr(
4299
+ _from_rbexpr(
3782
4300
  _rbexpr.rolling_std(
3783
4301
  window_size, weights, min_periods, center, by, closed, ddof, warn_if_unsorted
3784
4302
  )
@@ -3869,7 +4387,7 @@ module Polars
3869
4387
  window_size, min_periods = _prepare_rolling_window_args(
3870
4388
  window_size, min_periods
3871
4389
  )
3872
- wrap_expr(
4390
+ _from_rbexpr(
3873
4391
  _rbexpr.rolling_var(
3874
4392
  window_size, weights, min_periods, center, by, closed, ddof, warn_if_unsorted
3875
4393
  )
@@ -3955,7 +4473,7 @@ module Polars
3955
4473
  window_size, min_periods = _prepare_rolling_window_args(
3956
4474
  window_size, min_periods
3957
4475
  )
3958
- wrap_expr(
4476
+ _from_rbexpr(
3959
4477
  _rbexpr.rolling_median(
3960
4478
  window_size, weights, min_periods, center, by, closed, warn_if_unsorted
3961
4479
  )
@@ -4047,7 +4565,7 @@ module Polars
4047
4565
  window_size, min_periods = _prepare_rolling_window_args(
4048
4566
  window_size, min_periods
4049
4567
  )
4050
- wrap_expr(
4568
+ _from_rbexpr(
4051
4569
  _rbexpr.rolling_quantile(
4052
4570
  quantile, interpolation, window_size, weights, min_periods, center, by, closed, warn_if_unsorted
4053
4571
  )
@@ -4111,7 +4629,7 @@ module Polars
4111
4629
  # if min_periods.nil?
4112
4630
  # min_periods = window_size
4113
4631
  # end
4114
- # wrap_expr(
4632
+ # _from_rbexpr(
4115
4633
  # _rbexpr.rolling_apply(
4116
4634
  # function, window_size, weights, min_periods, center
4117
4635
  # )
@@ -4127,7 +4645,7 @@ module Polars
4127
4645
  #
4128
4646
  # @return [Expr]
4129
4647
  def rolling_skew(window_size, bias: true)
4130
- wrap_expr(_rbexpr.rolling_skew(window_size, bias))
4648
+ _from_rbexpr(_rbexpr.rolling_skew(window_size, bias))
4131
4649
  end
4132
4650
 
4133
4651
  # Compute absolute values.
@@ -4154,7 +4672,7 @@ module Polars
4154
4672
  # # │ 2.0 │
4155
4673
  # # └─────┘
4156
4674
  def abs
4157
- wrap_expr(_rbexpr.abs)
4675
+ _from_rbexpr(_rbexpr.abs)
4158
4676
  end
4159
4677
 
4160
4678
  # Get the index values that would sort this column.
@@ -4249,7 +4767,7 @@ module Polars
4249
4767
  # # │ 5 │
4250
4768
  # # └─────┘
4251
4769
  def rank(method: "average", reverse: false, seed: nil)
4252
- wrap_expr(_rbexpr.rank(method, reverse, seed))
4770
+ _from_rbexpr(_rbexpr.rank(method, reverse, seed))
4253
4771
  end
4254
4772
 
4255
4773
  # Calculate the n-th discrete difference.
@@ -4280,7 +4798,7 @@ module Polars
4280
4798
  # # │ 20 │
4281
4799
  # # └──────┘
4282
4800
  def diff(n: 1, null_behavior: "ignore")
4283
- wrap_expr(_rbexpr.diff(n, null_behavior))
4801
+ _from_rbexpr(_rbexpr.diff(n, null_behavior))
4284
4802
  end
4285
4803
 
4286
4804
  # Computes percentage change between values.
@@ -4317,7 +4835,7 @@ module Polars
4317
4835
  # # └──────┴────────────┘
4318
4836
  def pct_change(n: 1)
4319
4837
  n = Utils.parse_as_expression(n)
4320
- wrap_expr(_rbexpr.pct_change(n))
4838
+ _from_rbexpr(_rbexpr.pct_change(n))
4321
4839
  end
4322
4840
 
4323
4841
  # Compute the sample skewness of a data set.
@@ -4346,7 +4864,7 @@ module Polars
4346
4864
  # # │ 0.343622 │
4347
4865
  # # └──────────┘
4348
4866
  def skew(bias: true)
4349
- wrap_expr(_rbexpr.skew(bias))
4867
+ _from_rbexpr(_rbexpr.skew(bias))
4350
4868
  end
4351
4869
 
4352
4870
  # Compute the kurtosis (Fisher or Pearson) of a dataset.
@@ -4378,7 +4896,7 @@ module Polars
4378
4896
  # # │ -1.153061 │
4379
4897
  # # └───────────┘
4380
4898
  def kurtosis(fisher: true, bias: true)
4381
- wrap_expr(_rbexpr.kurtosis(fisher, bias))
4899
+ _from_rbexpr(_rbexpr.kurtosis(fisher, bias))
4382
4900
  end
4383
4901
 
4384
4902
  # Set values outside the given boundaries to the boundary value.
@@ -4415,7 +4933,7 @@ module Polars
4415
4933
  if !upper_bound.nil?
4416
4934
  upper_bound = Utils.parse_as_expression(upper_bound, str_as_lit: true)
4417
4935
  end
4418
- wrap_expr(_rbexpr.clip(lower_bound, upper_bound))
4936
+ _from_rbexpr(_rbexpr.clip(lower_bound, upper_bound))
4419
4937
  end
4420
4938
 
4421
4939
  # Clip (limit) the values in an array to a `min` boundary.
@@ -4500,7 +5018,7 @@ module Polars
4500
5018
  # # │ -9223372036854775808 │
4501
5019
  # # └──────────────────────┘
4502
5020
  def lower_bound
4503
- wrap_expr(_rbexpr.lower_bound)
5021
+ _from_rbexpr(_rbexpr.lower_bound)
4504
5022
  end
4505
5023
 
4506
5024
  # Calculate the upper bound.
@@ -4523,7 +5041,7 @@ module Polars
4523
5041
  # # │ 9223372036854775807 │
4524
5042
  # # └─────────────────────┘
4525
5043
  def upper_bound
4526
- wrap_expr(_rbexpr.upper_bound)
5044
+ _from_rbexpr(_rbexpr.upper_bound)
4527
5045
  end
4528
5046
 
4529
5047
  # Compute the element-wise indication of the sign.
@@ -4547,7 +5065,7 @@ module Polars
4547
5065
  # # │ null │
4548
5066
  # # └──────┘
4549
5067
  def sign
4550
- wrap_expr(_rbexpr.sign)
5068
+ _from_rbexpr(_rbexpr.sign)
4551
5069
  end
4552
5070
 
4553
5071
  # Compute the element-wise value for the sine.
@@ -4567,7 +5085,7 @@ module Polars
4567
5085
  # # │ 0.0 │
4568
5086
  # # └─────┘
4569
5087
  def sin
4570
- wrap_expr(_rbexpr.sin)
5088
+ _from_rbexpr(_rbexpr.sin)
4571
5089
  end
4572
5090
 
4573
5091
  # Compute the element-wise value for the cosine.
@@ -4587,7 +5105,7 @@ module Polars
4587
5105
  # # │ 1.0 │
4588
5106
  # # └─────┘
4589
5107
  def cos
4590
- wrap_expr(_rbexpr.cos)
5108
+ _from_rbexpr(_rbexpr.cos)
4591
5109
  end
4592
5110
 
4593
5111
  # Compute the element-wise value for the tangent.
@@ -4607,7 +5125,7 @@ module Polars
4607
5125
  # # │ 1.557408 │
4608
5126
  # # └──────────┘
4609
5127
  def tan
4610
- wrap_expr(_rbexpr.tan)
5128
+ _from_rbexpr(_rbexpr.tan)
4611
5129
  end
4612
5130
 
4613
5131
  # Compute the element-wise value for the inverse sine.
@@ -4627,7 +5145,7 @@ module Polars
4627
5145
  # # │ 1.570796 │
4628
5146
  # # └──────────┘
4629
5147
  def arcsin
4630
- wrap_expr(_rbexpr.arcsin)
5148
+ _from_rbexpr(_rbexpr.arcsin)
4631
5149
  end
4632
5150
 
4633
5151
  # Compute the element-wise value for the inverse cosine.
@@ -4647,7 +5165,7 @@ module Polars
4647
5165
  # # │ 1.570796 │
4648
5166
  # # └──────────┘
4649
5167
  def arccos
4650
- wrap_expr(_rbexpr.arccos)
5168
+ _from_rbexpr(_rbexpr.arccos)
4651
5169
  end
4652
5170
 
4653
5171
  # Compute the element-wise value for the inverse tangent.
@@ -4667,7 +5185,7 @@ module Polars
4667
5185
  # # │ 0.785398 │
4668
5186
  # # └──────────┘
4669
5187
  def arctan
4670
- wrap_expr(_rbexpr.arctan)
5188
+ _from_rbexpr(_rbexpr.arctan)
4671
5189
  end
4672
5190
 
4673
5191
  # Compute the element-wise value for the hyperbolic sine.
@@ -4687,7 +5205,7 @@ module Polars
4687
5205
  # # │ 1.175201 │
4688
5206
  # # └──────────┘
4689
5207
  def sinh
4690
- wrap_expr(_rbexpr.sinh)
5208
+ _from_rbexpr(_rbexpr.sinh)
4691
5209
  end
4692
5210
 
4693
5211
  # Compute the element-wise value for the hyperbolic cosine.
@@ -4707,7 +5225,7 @@ module Polars
4707
5225
  # # │ 1.543081 │
4708
5226
  # # └──────────┘
4709
5227
  def cosh
4710
- wrap_expr(_rbexpr.cosh)
5228
+ _from_rbexpr(_rbexpr.cosh)
4711
5229
  end
4712
5230
 
4713
5231
  # Compute the element-wise value for the hyperbolic tangent.
@@ -4727,7 +5245,7 @@ module Polars
4727
5245
  # # │ 0.761594 │
4728
5246
  # # └──────────┘
4729
5247
  def tanh
4730
- wrap_expr(_rbexpr.tanh)
5248
+ _from_rbexpr(_rbexpr.tanh)
4731
5249
  end
4732
5250
 
4733
5251
  # Compute the element-wise value for the inverse hyperbolic sine.
@@ -4747,7 +5265,7 @@ module Polars
4747
5265
  # # │ 0.881374 │
4748
5266
  # # └──────────┘
4749
5267
  def arcsinh
4750
- wrap_expr(_rbexpr.arcsinh)
5268
+ _from_rbexpr(_rbexpr.arcsinh)
4751
5269
  end
4752
5270
 
4753
5271
  # Compute the element-wise value for the inverse hyperbolic cosine.
@@ -4767,7 +5285,7 @@ module Polars
4767
5285
  # # │ 0.0 │
4768
5286
  # # └─────┘
4769
5287
  def arccosh
4770
- wrap_expr(_rbexpr.arccosh)
5288
+ _from_rbexpr(_rbexpr.arccosh)
4771
5289
  end
4772
5290
 
4773
5291
  # Compute the element-wise value for the inverse hyperbolic tangent.
@@ -4787,7 +5305,7 @@ module Polars
4787
5305
  # # │ inf │
4788
5306
  # # └─────┘
4789
5307
  def arctanh
4790
- wrap_expr(_rbexpr.arctanh)
5308
+ _from_rbexpr(_rbexpr.arctanh)
4791
5309
  end
4792
5310
 
4793
5311
  # Reshape this Expr to a flat Series or a Series of Lists.
@@ -4813,7 +5331,7 @@ module Polars
4813
5331
  # # │ [7, 8, 9] │
4814
5332
  # # └───────────┘
4815
5333
  def reshape(dims)
4816
- wrap_expr(_rbexpr.reshape(dims))
5334
+ _from_rbexpr(_rbexpr.reshape(dims))
4817
5335
  end
4818
5336
 
4819
5337
  # Shuffle the contents of this expr.
@@ -4842,7 +5360,7 @@ module Polars
4842
5360
  if seed.nil?
4843
5361
  seed = rand(10000)
4844
5362
  end
4845
- wrap_expr(_rbexpr.shuffle(seed))
5363
+ _from_rbexpr(_rbexpr.shuffle(seed))
4846
5364
  end
4847
5365
 
4848
5366
  # Sample from this expression.
@@ -4888,14 +5406,14 @@ module Polars
4888
5406
 
4889
5407
  if !n.nil? && frac.nil?
4890
5408
  n = Utils.parse_as_expression(n)
4891
- return wrap_expr(_rbexpr.sample_n(n, with_replacement, shuffle, seed))
5409
+ return _from_rbexpr(_rbexpr.sample_n(n, with_replacement, shuffle, seed))
4892
5410
  end
4893
5411
 
4894
5412
  if frac.nil?
4895
5413
  frac = 1.0
4896
5414
  end
4897
5415
  frac = Utils.parse_as_expression(frac)
4898
- wrap_expr(
5416
+ _from_rbexpr(
4899
5417
  _rbexpr.sample_frac(frac, with_replacement, shuffle, seed)
4900
5418
  )
4901
5419
  end
@@ -4928,7 +5446,7 @@ module Polars
4928
5446
  ignore_nulls: true
4929
5447
  )
4930
5448
  alpha = _prepare_alpha(com, span, half_life, alpha)
4931
- wrap_expr(_rbexpr.ewm_mean(alpha, adjust, min_periods, ignore_nulls))
5449
+ _from_rbexpr(_rbexpr.ewm_mean(alpha, adjust, min_periods, ignore_nulls))
4932
5450
  end
4933
5451
 
4934
5452
  # Exponentially-weighted moving standard deviation.
@@ -4960,7 +5478,7 @@ module Polars
4960
5478
  ignore_nulls: true
4961
5479
  )
4962
5480
  alpha = _prepare_alpha(com, span, half_life, alpha)
4963
- wrap_expr(_rbexpr.ewm_std(alpha, adjust, bias, min_periods, ignore_nulls))
5481
+ _from_rbexpr(_rbexpr.ewm_std(alpha, adjust, bias, min_periods, ignore_nulls))
4964
5482
  end
4965
5483
 
4966
5484
  # Exponentially-weighted moving variance.
@@ -4992,7 +5510,7 @@ module Polars
4992
5510
  ignore_nulls: true
4993
5511
  )
4994
5512
  alpha = _prepare_alpha(com, span, half_life, alpha)
4995
- wrap_expr(_rbexpr.ewm_var(alpha, adjust, bias, min_periods, ignore_nulls))
5513
+ _from_rbexpr(_rbexpr.ewm_var(alpha, adjust, bias, min_periods, ignore_nulls))
4996
5514
  end
4997
5515
 
4998
5516
  # Extend the Series with given number of values.
@@ -5022,7 +5540,7 @@ module Polars
5022
5540
  # # │ 99 │
5023
5541
  # # └────────┘
5024
5542
  def extend_constant(value, n)
5025
- wrap_expr(_rbexpr.extend_constant(value, n))
5543
+ _from_rbexpr(_rbexpr.extend_constant(value, n))
5026
5544
  end
5027
5545
 
5028
5546
  # Count all unique values and create a struct mapping value to count.
@@ -5058,7 +5576,7 @@ module Polars
5058
5576
  # # │ {"a",1} │
5059
5577
  # # └───────────┘
5060
5578
  def value_counts(multithreaded: false, sort: false)
5061
- wrap_expr(_rbexpr.value_counts(multithreaded, sort))
5579
+ _from_rbexpr(_rbexpr.value_counts(multithreaded, sort))
5062
5580
  end
5063
5581
 
5064
5582
  # Return a count of the unique values in the order of appearance.
@@ -5091,7 +5609,7 @@ module Polars
5091
5609
  # # │ 3 │
5092
5610
  # # └─────┘
5093
5611
  def unique_counts
5094
- wrap_expr(_rbexpr.unique_counts)
5612
+ _from_rbexpr(_rbexpr.unique_counts)
5095
5613
  end
5096
5614
 
5097
5615
  # Compute the logarithm to a given base.
@@ -5116,7 +5634,7 @@ module Polars
5116
5634
  # # │ 1.584963 │
5117
5635
  # # └──────────┘
5118
5636
  def log(base = Math::E)
5119
- wrap_expr(_rbexpr.log(base))
5637
+ _from_rbexpr(_rbexpr.log(base))
5120
5638
  end
5121
5639
 
5122
5640
  # Computes the entropy.
@@ -5155,7 +5673,7 @@ module Polars
5155
5673
  # # │ -6.754888 │
5156
5674
  # # └───────────┘
5157
5675
  def entropy(base: 2, normalize: true)
5158
- wrap_expr(_rbexpr.entropy(base, normalize))
5676
+ _from_rbexpr(_rbexpr.entropy(base, normalize))
5159
5677
  end
5160
5678
 
5161
5679
  # Run an expression over a sliding window that increases `1` slot every iteration.
@@ -5202,7 +5720,7 @@ module Polars
5202
5720
  # # │ -24.0 │
5203
5721
  # # └────────┘
5204
5722
  def cumulative_eval(expr, min_periods: 1, parallel: false)
5205
- wrap_expr(
5723
+ _from_rbexpr(
5206
5724
  _rbexpr.cumulative_eval(expr._rbexpr, min_periods, parallel)
5207
5725
  )
5208
5726
  end
@@ -5233,7 +5751,7 @@ module Polars
5233
5751
  # # │ 3 │
5234
5752
  # # └────────┘
5235
5753
  def set_sorted(descending: false)
5236
- wrap_expr(_rbexpr.set_sorted_flag(descending))
5754
+ _from_rbexpr(_rbexpr.set_sorted_flag(descending))
5237
5755
  end
5238
5756
 
5239
5757
  # Aggregate to list.
@@ -5258,7 +5776,7 @@ module Polars
5258
5776
  # # │ [1, 2, 3] ┆ [4, 5, 6] │
5259
5777
  # # └───────────┴───────────┘
5260
5778
  def implode
5261
- wrap_expr(_rbexpr.implode)
5779
+ _from_rbexpr(_rbexpr.implode)
5262
5780
  end
5263
5781
 
5264
5782
  # Shrink numeric columns to the minimal required datatype.
@@ -5293,7 +5811,169 @@ module Polars
5293
5811
  # # │ 3 ┆ 8589934592 ┆ 1073741824 ┆ 112 ┆ 129 ┆ c ┆ 0.12 ┆ false │
5294
5812
  # # └─────┴────────────┴────────────┴──────┴──────┴─────┴──────┴───────┘
5295
5813
  def shrink_dtype
5296
- wrap_expr(_rbexpr.shrink_dtype)
5814
+ _from_rbexpr(_rbexpr.shrink_dtype)
5815
+ end
5816
+
5817
+ # Replace values by different values.
5818
+ #
5819
+ # @param old [Object]
5820
+ # Value or sequence of values to replace.
5821
+ # Accepts expression input. Sequences are parsed as Series,
5822
+ # other non-expression inputs are parsed as literals.
5823
+ # Also accepts a mapping of values to their replacement.
5824
+ # @param new [Object]
5825
+ # Value or sequence of values to replace by.
5826
+ # Accepts expression input. Sequences are parsed as Series,
5827
+ # other non-expression inputs are parsed as literals.
5828
+ # Length must match the length of `old` or have length 1.
5829
+ # @param default [Object]
5830
+ # Set values that were not replaced to this value.
5831
+ # Defaults to keeping the original value.
5832
+ # Accepts expression input. Non-expression inputs are parsed as literals.
5833
+ # @param return_dtype [Object]
5834
+ # The data type of the resulting expression. If set to `nil` (default),
5835
+ # the data type is determined automatically based on the other inputs.
5836
+ #
5837
+ # @return [Expr]
5838
+ #
5839
+ # @example Replace a single value by another value. Values that were not replaced remain unchanged.
5840
+ # df = Polars::DataFrame.new({"a" => [1, 2, 2, 3]})
5841
+ # df.with_columns(replaced: Polars.col("a").replace(2, 100))
5842
+ # # =>
5843
+ # # shape: (4, 2)
5844
+ # # ┌─────┬──────────┐
5845
+ # # │ a ┆ replaced │
5846
+ # # │ --- ┆ --- │
5847
+ # # │ i64 ┆ i64 │
5848
+ # # ╞═════╪══════════╡
5849
+ # # │ 1 ┆ 1 │
5850
+ # # │ 2 ┆ 100 │
5851
+ # # │ 2 ┆ 100 │
5852
+ # # │ 3 ┆ 3 │
5853
+ # # └─────┴──────────┘
5854
+ #
5855
+ # @example Replace multiple values by passing sequences to the `old` and `new` parameters.
5856
+ # df.with_columns(replaced: Polars.col("a").replace([2, 3], [100, 200]))
5857
+ # # =>
5858
+ # # shape: (4, 2)
5859
+ # # ┌─────┬──────────┐
5860
+ # # │ a ┆ replaced │
5861
+ # # │ --- ┆ --- │
5862
+ # # │ i64 ┆ i64 │
5863
+ # # ╞═════╪══════════╡
5864
+ # # │ 1 ┆ 1 │
5865
+ # # │ 2 ┆ 100 │
5866
+ # # │ 2 ┆ 100 │
5867
+ # # │ 3 ┆ 200 │
5868
+ # # └─────┴──────────┘
5869
+ #
5870
+ # @example Passing a mapping with replacements is also supported as syntactic sugar. Specify a default to set all values that were not matched.
5871
+ # mapping = {2 => 100, 3 => 200}
5872
+ # df.with_columns(replaced: Polars.col("a").replace(mapping, default: -1))
5873
+ # # =>
5874
+ # # shape: (4, 2)
5875
+ # # ┌─────┬──────────┐
5876
+ # # │ a ┆ replaced │
5877
+ # # │ --- ┆ --- │
5878
+ # # │ i64 ┆ i64 │
5879
+ # # ╞═════╪══════════╡
5880
+ # # │ 1 ┆ -1 │
5881
+ # # │ 2 ┆ 100 │
5882
+ # # │ 2 ┆ 100 │
5883
+ # # │ 3 ┆ 200 │
5884
+ # # └─────┴──────────┘
5885
+ #
5886
+ # @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.
5887
+ # df = Polars::DataFrame.new({"a" => ["x", "y", "z"]})
5888
+ # mapping = {"x" => 1, "y" => 2, "z" => 3}
5889
+ # df.with_columns(replaced: Polars.col("a").replace(mapping))
5890
+ # # =>
5891
+ # # shape: (3, 2)
5892
+ # # ┌─────┬──────────┐
5893
+ # # │ a ┆ replaced │
5894
+ # # │ --- ┆ --- │
5895
+ # # │ str ┆ str │
5896
+ # # ╞═════╪══════════╡
5897
+ # # │ x ┆ 1 │
5898
+ # # │ y ┆ 2 │
5899
+ # # │ z ┆ 3 │
5900
+ # # └─────┴──────────┘
5901
+ #
5902
+ # @example
5903
+ # df.with_columns(replaced: Polars.col("a").replace(mapping, default: nil))
5904
+ # # =>
5905
+ # # shape: (3, 2)
5906
+ # # ┌─────┬──────────┐
5907
+ # # │ a ┆ replaced │
5908
+ # # │ --- ┆ --- │
5909
+ # # │ str ┆ i64 │
5910
+ # # ╞═════╪══════════╡
5911
+ # # │ x ┆ 1 │
5912
+ # # │ y ┆ 2 │
5913
+ # # │ z ┆ 3 │
5914
+ # # └─────┴──────────┘
5915
+ #
5916
+ # @example Set the `return_dtype` parameter to control the resulting data type directly.
5917
+ # df.with_columns(
5918
+ # replaced: Polars.col("a").replace(mapping, return_dtype: Polars::UInt8)
5919
+ # )
5920
+ # # =>
5921
+ # # shape: (3, 2)
5922
+ # # ┌─────┬──────────┐
5923
+ # # │ a ┆ replaced │
5924
+ # # │ --- ┆ --- │
5925
+ # # │ str ┆ u8 │
5926
+ # # ╞═════╪══════════╡
5927
+ # # │ x ┆ 1 │
5928
+ # # │ y ┆ 2 │
5929
+ # # │ z ┆ 3 │
5930
+ # # └─────┴──────────┘
5931
+ #
5932
+ # @example Expression input is supported for all parameters.
5933
+ # df = Polars::DataFrame.new({"a" => [1, 2, 2, 3], "b" => [1.5, 2.5, 5.0, 1.0]})
5934
+ # df.with_columns(
5935
+ # replaced: Polars.col("a").replace(
5936
+ # Polars.col("a").max,
5937
+ # Polars.col("b").sum,
5938
+ # default: Polars.col("b")
5939
+ # )
5940
+ # )
5941
+ # # =>
5942
+ # # shape: (4, 3)
5943
+ # # ┌─────┬─────┬──────────┐
5944
+ # # │ a ┆ b ┆ replaced │
5945
+ # # │ --- ┆ --- ┆ --- │
5946
+ # # │ i64 ┆ f64 ┆ f64 │
5947
+ # # ╞═════╪═════╪══════════╡
5948
+ # # │ 1 ┆ 1.5 ┆ 1.5 │
5949
+ # # │ 2 ┆ 2.5 ┆ 2.5 │
5950
+ # # │ 2 ┆ 5.0 ┆ 5.0 │
5951
+ # # │ 3 ┆ 1.0 ┆ 10.0 │
5952
+ # # └─────┴─────┴──────────┘
5953
+ def replace(old, new = NO_DEFAULT, default: NO_DEFAULT, return_dtype: nil)
5954
+ if new.eql?(NO_DEFAULT) && old.is_a?(Hash)
5955
+ new = Series.new(old.values)
5956
+ old = Series.new(old.keys)
5957
+ else
5958
+ if old.is_a?(::Array)
5959
+ old = Series.new(old)
5960
+ end
5961
+ if new.is_a?(::Array)
5962
+ new = Series.new(new)
5963
+ end
5964
+ end
5965
+
5966
+ old = Utils.parse_as_expression(old, str_as_lit: true)
5967
+ new = Utils.parse_as_expression(new, str_as_lit: true)
5968
+
5969
+ default =
5970
+ if default.eql?(NO_DEFAULT)
5971
+ nil
5972
+ else
5973
+ Utils.parse_as_expression(default, str_as_lit: true)
5974
+ end
5975
+
5976
+ _from_rbexpr(_rbexpr.replace(old, new, default, return_dtype))
5297
5977
  end
5298
5978
 
5299
5979
  # Create an object namespace of all list related methods.
@@ -5361,7 +6041,7 @@ module Polars
5361
6041
 
5362
6042
  private
5363
6043
 
5364
- def wrap_expr(expr)
6044
+ def _from_rbexpr(expr)
5365
6045
  Utils.wrap_expr(expr)
5366
6046
  end
5367
6047