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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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