polars-df 0.15.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +274 -0
  3. data/Cargo.lock +1465 -867
  4. data/Cargo.toml +3 -0
  5. data/LICENSE.txt +2 -2
  6. data/README.md +87 -37
  7. data/ext/polars/Cargo.toml +47 -16
  8. data/ext/polars/src/c_api/allocator.rs +7 -0
  9. data/ext/polars/src/c_api/mod.rs +1 -0
  10. data/ext/polars/src/catalog/mod.rs +1 -0
  11. data/ext/polars/src/catalog/unity.rs +470 -0
  12. data/ext/polars/src/conversion/any_value.rs +99 -84
  13. data/ext/polars/src/conversion/categorical.rs +30 -0
  14. data/ext/polars/src/conversion/chunked_array.rs +71 -62
  15. data/ext/polars/src/conversion/datetime.rs +63 -0
  16. data/ext/polars/src/conversion/mod.rs +796 -312
  17. data/ext/polars/src/dataframe/construction.rs +6 -18
  18. data/ext/polars/src/dataframe/export.rs +30 -39
  19. data/ext/polars/src/dataframe/general.rs +294 -362
  20. data/ext/polars/src/dataframe/io.rs +33 -150
  21. data/ext/polars/src/dataframe/map.rs +175 -0
  22. data/ext/polars/src/dataframe/mod.rs +37 -5
  23. data/ext/polars/src/dataframe/serde.rs +23 -8
  24. data/ext/polars/src/error.rs +44 -7
  25. data/ext/polars/src/exceptions.rs +21 -8
  26. data/ext/polars/src/expr/array.rs +86 -22
  27. data/ext/polars/src/expr/binary.rs +50 -1
  28. data/ext/polars/src/expr/bitwise.rs +39 -0
  29. data/ext/polars/src/expr/categorical.rs +20 -0
  30. data/ext/polars/src/expr/datatype.rs +51 -0
  31. data/ext/polars/src/expr/datetime.rs +99 -41
  32. data/ext/polars/src/expr/extension.rs +12 -0
  33. data/ext/polars/src/expr/general.rs +252 -128
  34. data/ext/polars/src/expr/list.rs +56 -60
  35. data/ext/polars/src/expr/meta.rs +30 -35
  36. data/ext/polars/src/expr/mod.rs +28 -6
  37. data/ext/polars/src/expr/name.rs +29 -14
  38. data/ext/polars/src/expr/rolling.rs +111 -3
  39. data/ext/polars/src/expr/selector.rs +219 -0
  40. data/ext/polars/src/expr/serde.rs +28 -0
  41. data/ext/polars/src/expr/string.rs +118 -20
  42. data/ext/polars/src/expr/struct.rs +14 -1
  43. data/ext/polars/src/file.rs +194 -86
  44. data/ext/polars/src/functions/aggregation.rs +13 -12
  45. data/ext/polars/src/functions/business.rs +2 -3
  46. data/ext/polars/src/functions/eager.rs +3 -2
  47. data/ext/polars/src/functions/io.rs +90 -18
  48. data/ext/polars/src/functions/lazy.rs +267 -118
  49. data/ext/polars/src/functions/meta.rs +8 -7
  50. data/ext/polars/src/functions/misc.rs +1 -1
  51. data/ext/polars/src/functions/mod.rs +2 -1
  52. data/ext/polars/src/functions/range.rs +88 -31
  53. data/ext/polars/src/functions/strings.rs +6 -0
  54. data/ext/polars/src/functions/utils.rs +8 -0
  55. data/ext/polars/src/interop/arrow/mod.rs +52 -1
  56. data/ext/polars/src/interop/arrow/{to_ruby.rs → to_rb.rs} +37 -7
  57. data/ext/polars/src/interop/arrow/to_rust.rs +43 -0
  58. data/ext/polars/src/interop/numo/to_numo_df.rs +1 -1
  59. data/ext/polars/src/interop/numo/to_numo_series.rs +72 -50
  60. data/ext/polars/src/io/cloud_options.rs +107 -0
  61. data/ext/polars/src/io/mod.rs +4 -0
  62. data/ext/polars/src/io/scan_options.rs +113 -0
  63. data/ext/polars/src/io/sink_options.rs +46 -0
  64. data/ext/polars/src/io/sink_output.rs +21 -0
  65. data/ext/polars/src/lazyframe/exitable.rs +39 -0
  66. data/ext/polars/src/lazyframe/general.rs +846 -368
  67. data/ext/polars/src/lazyframe/mod.rs +58 -5
  68. data/ext/polars/src/lazyframe/optflags.rs +59 -0
  69. data/ext/polars/src/lazyframe/serde.rs +36 -4
  70. data/ext/polars/src/lazyframe/sink.rs +46 -0
  71. data/ext/polars/src/lazygroupby.rs +38 -9
  72. data/ext/polars/src/lib.rs +574 -165
  73. data/ext/polars/src/map/lazy.rs +44 -74
  74. data/ext/polars/src/map/mod.rs +18 -254
  75. data/ext/polars/src/map/series.rs +241 -1087
  76. data/ext/polars/src/on_startup.rs +192 -9
  77. data/ext/polars/src/prelude.rs +1 -0
  78. data/ext/polars/src/rb_modules.rs +10 -57
  79. data/ext/polars/src/ruby/exceptions.rs +26 -0
  80. data/ext/polars/src/ruby/gvl.rs +104 -0
  81. data/ext/polars/src/ruby/lazy.rs +46 -0
  82. data/ext/polars/src/ruby/mod.rs +11 -0
  83. data/ext/polars/src/ruby/numo.rs +52 -0
  84. data/ext/polars/src/ruby/plan_callback.rs +198 -0
  85. data/ext/polars/src/ruby/rb_modules.rs +16 -0
  86. data/ext/polars/src/ruby/ruby_convert_registry.rs +51 -0
  87. data/ext/polars/src/ruby/ruby_function.rs +11 -0
  88. data/ext/polars/src/ruby/ruby_udf.rs +164 -0
  89. data/ext/polars/src/ruby/thread.rs +65 -0
  90. data/ext/polars/src/ruby/utils.rs +39 -0
  91. data/ext/polars/src/series/aggregation.rs +116 -91
  92. data/ext/polars/src/series/arithmetic.rs +16 -22
  93. data/ext/polars/src/series/comparison.rs +101 -222
  94. data/ext/polars/src/series/construction.rs +80 -70
  95. data/ext/polars/src/series/export.rs +98 -56
  96. data/ext/polars/src/series/general.rs +323 -440
  97. data/ext/polars/src/series/import.rs +22 -5
  98. data/ext/polars/src/series/map.rs +103 -0
  99. data/ext/polars/src/series/mod.rs +57 -15
  100. data/ext/polars/src/series/scatter.rs +139 -82
  101. data/ext/polars/src/sql.rs +16 -9
  102. data/ext/polars/src/testing/frame.rs +31 -0
  103. data/ext/polars/src/testing/mod.rs +5 -0
  104. data/ext/polars/src/testing/series.rs +31 -0
  105. data/ext/polars/src/timeout.rs +105 -0
  106. data/ext/polars/src/utils.rs +105 -4
  107. data/lib/polars/array_expr.rb +500 -22
  108. data/lib/polars/array_name_space.rb +384 -10
  109. data/lib/polars/batched_csv_reader.rb +48 -66
  110. data/lib/polars/binary_expr.rb +217 -0
  111. data/lib/polars/binary_name_space.rb +155 -1
  112. data/lib/polars/cat_expr.rb +224 -0
  113. data/lib/polars/cat_name_space.rb +132 -32
  114. data/lib/polars/catalog/unity/catalog_info.rb +20 -0
  115. data/lib/polars/catalog/unity/column_info.rb +31 -0
  116. data/lib/polars/catalog/unity/namespace_info.rb +21 -0
  117. data/lib/polars/catalog/unity/table_info.rb +50 -0
  118. data/lib/polars/catalog.rb +448 -0
  119. data/lib/polars/collect_batches.rb +22 -0
  120. data/lib/polars/config.rb +3 -3
  121. data/lib/polars/convert.rb +201 -36
  122. data/lib/polars/data_frame.rb +2851 -1017
  123. data/lib/polars/data_frame_plot.rb +173 -0
  124. data/lib/polars/data_type_expr.rb +52 -0
  125. data/lib/polars/data_type_group.rb +6 -0
  126. data/lib/polars/data_types.rb +118 -18
  127. data/lib/polars/date_time_expr.rb +426 -84
  128. data/lib/polars/date_time_name_space.rb +384 -111
  129. data/lib/polars/dynamic_group_by.rb +102 -10
  130. data/lib/polars/exceptions.rb +50 -5
  131. data/lib/polars/expr.rb +2159 -915
  132. data/lib/polars/extension_expr.rb +39 -0
  133. data/lib/polars/extension_name_space.rb +39 -0
  134. data/lib/polars/functions/aggregation/horizontal.rb +11 -6
  135. data/lib/polars/functions/aggregation/vertical.rb +2 -3
  136. data/lib/polars/functions/as_datatype.rb +290 -8
  137. data/lib/polars/functions/business.rb +95 -0
  138. data/lib/polars/functions/col.rb +6 -5
  139. data/lib/polars/functions/datatype.rb +62 -0
  140. data/lib/polars/functions/eager.rb +426 -24
  141. data/lib/polars/functions/escape_regex.rb +21 -0
  142. data/lib/polars/functions/lazy.rb +813 -195
  143. data/lib/polars/functions/lit.rb +21 -10
  144. data/lib/polars/functions/range/int_range.rb +74 -2
  145. data/lib/polars/functions/range/linear_space.rb +195 -0
  146. data/lib/polars/functions/range/time_range.rb +1 -1
  147. data/lib/polars/functions/repeat.rb +7 -12
  148. data/lib/polars/functions/whenthen.rb +2 -2
  149. data/lib/polars/group_by.rb +188 -58
  150. data/lib/polars/iceberg_dataset.rb +108 -0
  151. data/lib/polars/in_process_query.rb +37 -0
  152. data/lib/polars/io/cloud.rb +18 -0
  153. data/lib/polars/io/csv.rb +336 -128
  154. data/lib/polars/io/database.rb +19 -4
  155. data/lib/polars/io/delta.rb +134 -0
  156. data/lib/polars/io/iceberg.rb +34 -0
  157. data/lib/polars/io/ipc.rb +63 -63
  158. data/lib/polars/io/json.rb +16 -0
  159. data/lib/polars/io/lines.rb +172 -0
  160. data/lib/polars/io/ndjson.rb +176 -20
  161. data/lib/polars/io/parquet.rb +173 -95
  162. data/lib/polars/io/scan_options.rb +55 -0
  163. data/lib/polars/io/sink_options.rb +27 -0
  164. data/lib/polars/io/utils.rb +17 -0
  165. data/lib/polars/lazy_frame.rb +3017 -622
  166. data/lib/polars/lazy_group_by.rb +436 -2
  167. data/lib/polars/list_expr.rb +551 -59
  168. data/lib/polars/list_name_space.rb +465 -51
  169. data/lib/polars/meta_expr.rb +146 -24
  170. data/lib/polars/name_expr.rb +87 -2
  171. data/lib/polars/query_opt_flags.rb +264 -0
  172. data/lib/polars/rolling_group_by.rb +90 -5
  173. data/lib/polars/scan_cast_options.rb +86 -0
  174. data/lib/polars/schema.rb +128 -0
  175. data/lib/polars/selector.rb +245 -0
  176. data/lib/polars/selectors.rb +1048 -201
  177. data/lib/polars/series.rb +2522 -774
  178. data/lib/polars/series_plot.rb +72 -0
  179. data/lib/polars/slice.rb +1 -1
  180. data/lib/polars/sql_context.rb +13 -6
  181. data/lib/polars/string_cache.rb +19 -72
  182. data/lib/polars/string_expr.rb +561 -107
  183. data/lib/polars/string_name_space.rb +781 -109
  184. data/lib/polars/struct_expr.rb +139 -18
  185. data/lib/polars/struct_name_space.rb +19 -1
  186. data/lib/polars/testing.rb +24 -273
  187. data/lib/polars/utils/constants.rb +2 -0
  188. data/lib/polars/utils/construction/data_frame.rb +410 -0
  189. data/lib/polars/utils/construction/series.rb +350 -0
  190. data/lib/polars/utils/construction/utils.rb +9 -0
  191. data/lib/polars/utils/convert.rb +18 -8
  192. data/lib/polars/utils/deprecation.rb +11 -0
  193. data/lib/polars/utils/parse.rb +62 -9
  194. data/lib/polars/utils/reduce_balanced.rb +43 -0
  195. data/lib/polars/utils/serde.rb +22 -0
  196. data/lib/polars/utils/unstable.rb +19 -0
  197. data/lib/polars/utils/various.rb +86 -1
  198. data/lib/polars/utils.rb +63 -48
  199. data/lib/polars/version.rb +1 -1
  200. data/lib/polars.rb +85 -2
  201. metadata +80 -28
  202. data/ext/polars/src/allocator.rs +0 -13
  203. data/ext/polars/src/batched_csv.rs +0 -138
  204. data/ext/polars/src/functions/string_cache.rs +0 -25
  205. data/ext/polars/src/map/dataframe.rs +0 -338
  206. data/lib/polars/plot.rb +0 -109
@@ -1,15 +1,17 @@
1
1
  use std::ops::Neg;
2
2
 
3
- use magnus::{prelude::*, value::Opaque, IntoValue, RArray, Ruby, Value};
3
+ use magnus::RArray;
4
4
  use polars::lazy::dsl;
5
5
  use polars::prelude::*;
6
6
  use polars::series::ops::NullBehavior;
7
- use polars_core::series::IsSorted;
7
+ use polars_core::chunked_array::cast::CastOptions;
8
+ use polars_plan::plans::AExprSorted;
8
9
 
9
- use crate::conversion::{parse_fill_null_strategy, Wrap};
10
- use crate::map::lazy::map_single;
11
- use crate::rb_exprs_to_exprs;
12
- use crate::{RbExpr, RbResult};
10
+ use super::datatype::RbDataTypeExpr;
11
+ use super::selector::RbSelector;
12
+ use crate::conversion::{Wrap, parse_fill_null_strategy};
13
+ use crate::expr::ToExprs;
14
+ use crate::{RbDataType, RbExpr, RbPolarsErr, RbResult};
13
15
 
14
16
  impl RbExpr {
15
17
  pub fn add(&self, rhs: &Self) -> RbResult<Self> {
@@ -116,6 +118,14 @@ impl RbExpr {
116
118
  self.inner.clone().max().into()
117
119
  }
118
120
 
121
+ pub fn min_by(&self, by: &Self) -> Self {
122
+ self.inner.clone().min_by(by.inner.clone()).into()
123
+ }
124
+
125
+ pub fn max_by(&self, by: &Self) -> Self {
126
+ self.inner.clone().max_by(by.inner.clone()).into()
127
+ }
128
+
119
129
  pub fn nan_max(&self) -> Self {
120
130
  self.inner.clone().nan_max().into()
121
131
  }
@@ -152,16 +162,28 @@ impl RbExpr {
152
162
  self.inner.clone().unique_stable().into()
153
163
  }
154
164
 
155
- pub fn first(&self) -> Self {
156
- self.inner.clone().first().into()
165
+ pub fn first(&self, ignore_nulls: bool) -> Self {
166
+ if ignore_nulls {
167
+ self.inner.clone().first_non_null().into()
168
+ } else {
169
+ self.inner.clone().first().into()
170
+ }
157
171
  }
158
172
 
159
- pub fn last(&self) -> Self {
160
- self.inner.clone().last().into()
173
+ pub fn last(&self, ignore_nulls: bool) -> Self {
174
+ if ignore_nulls {
175
+ self.inner.clone().last_non_null().into()
176
+ } else {
177
+ self.inner.clone().last().into()
178
+ }
179
+ }
180
+
181
+ pub fn item(&self, allow_empty: bool) -> Self {
182
+ self.inner.clone().item(allow_empty).into()
161
183
  }
162
184
 
163
- pub fn implode(&self) -> Self {
164
- self.inner.clone().implode().into()
185
+ pub fn implode(&self, maintain_order: bool) -> Self {
186
+ self.inner.clone().implode(maintain_order).into()
165
187
  }
166
188
 
167
189
  pub fn quantile(&self, quantile: &Self, interpolation: Wrap<QuantileMethod>) -> Self {
@@ -253,14 +275,20 @@ impl RbExpr {
253
275
  self.inner.clone().null_count().into()
254
276
  }
255
277
 
256
- pub fn cast(&self, data_type: Wrap<DataType>, strict: bool) -> RbResult<Self> {
257
- let dt = data_type.0;
258
- let expr = if strict {
259
- self.inner.clone().strict_cast(dt)
278
+ pub fn cast(&self, dtype: &RbDataTypeExpr, strict: bool, wrap_numerical: bool) -> Self {
279
+ let options = if wrap_numerical {
280
+ CastOptions::Overflowing
281
+ } else if strict {
282
+ CastOptions::Strict
260
283
  } else {
261
- self.inner.clone().cast(dt)
284
+ CastOptions::NonStrict
262
285
  };
263
- Ok(expr.into())
286
+
287
+ let expr = self
288
+ .inner
289
+ .clone()
290
+ .cast_with_options(dtype.inner.clone(), options);
291
+ expr.into()
264
292
  }
265
293
 
266
294
  pub fn sort_with(&self, descending: bool, nulls_last: bool) -> Self {
@@ -271,20 +299,13 @@ impl RbExpr {
271
299
  nulls_last,
272
300
  multithreaded: true,
273
301
  maintain_order: false,
302
+ limit: None,
274
303
  })
275
304
  .into()
276
305
  }
277
306
 
278
- pub fn arg_sort(&self, reverse: bool, nulls_last: bool) -> Self {
279
- self.clone()
280
- .inner
281
- .arg_sort(SortOptions {
282
- descending: reverse,
283
- nulls_last,
284
- multithreaded: true,
285
- maintain_order: false,
286
- })
287
- .into()
307
+ pub fn arg_sort(&self, descending: bool, nulls_last: bool) -> Self {
308
+ self.inner.clone().arg_sort(descending, nulls_last).into()
288
309
  }
289
310
 
290
311
  pub fn top_k(&self, k: &Self) -> Self {
@@ -292,7 +313,7 @@ impl RbExpr {
292
313
  }
293
314
 
294
315
  pub fn top_k_by(&self, by: RArray, k: &Self, reverse: Vec<bool>) -> RbResult<Self> {
295
- let by = rb_exprs_to_exprs(by)?;
316
+ let by = by.to_exprs()?;
296
317
  Ok(self
297
318
  .inner
298
319
  .clone()
@@ -305,7 +326,7 @@ impl RbExpr {
305
326
  }
306
327
 
307
328
  pub fn bottom_k_by(&self, by: RArray, k: &Self, reverse: Vec<bool>) -> RbResult<Self> {
308
- let by = rb_exprs_to_exprs(by)?;
329
+ let by = by.to_exprs()?;
309
330
  Ok(self
310
331
  .inner
311
332
  .clone()
@@ -329,19 +350,34 @@ impl RbExpr {
329
350
  self.inner.clone().arg_min().into()
330
351
  }
331
352
 
332
- pub fn search_sorted(&self, element: &Self, side: Wrap<SearchSortedSide>) -> Self {
353
+ pub fn index_of(&self, element: &Self) -> Self {
354
+ self.inner.clone().index_of(element.inner.clone()).into()
355
+ }
356
+
357
+ pub fn search_sorted(
358
+ &self,
359
+ element: &Self,
360
+ side: Wrap<SearchSortedSide>,
361
+ descending: bool,
362
+ ) -> Self {
333
363
  self.inner
334
364
  .clone()
335
- .search_sorted(element.inner.clone(), side.0)
365
+ .search_sorted(element.inner.clone(), side.0, descending)
336
366
  .into()
337
367
  }
338
368
 
339
- pub fn gather(&self, idx: &Self) -> Self {
340
- self.inner.clone().gather(idx.inner.clone()).into()
369
+ pub fn gather(&self, idx: &Self, null_on_oob: bool) -> Self {
370
+ self.inner
371
+ .clone()
372
+ .gather(idx.inner.clone(), null_on_oob)
373
+ .into()
341
374
  }
342
375
 
343
- pub fn get(&self, idx: &Self) -> Self {
344
- self.inner.clone().get(idx.inner.clone()).into()
376
+ pub fn get(&self, idx: &Self, null_on_oob: bool) -> Self {
377
+ self.inner
378
+ .clone()
379
+ .get(idx.inner.clone(), null_on_oob)
380
+ .into()
345
381
  }
346
382
 
347
383
  pub fn sort_by(
@@ -352,7 +388,7 @@ impl RbExpr {
352
388
  multithreaded: bool,
353
389
  maintain_order: bool,
354
390
  ) -> RbResult<Self> {
355
- let by = rb_exprs_to_exprs(by)?;
391
+ let by = by.to_exprs()?;
356
392
  Ok(self
357
393
  .inner
358
394
  .clone()
@@ -363,19 +399,12 @@ impl RbExpr {
363
399
  nulls_last,
364
400
  multithreaded,
365
401
  maintain_order,
402
+ limit: None,
366
403
  },
367
404
  )
368
405
  .into())
369
406
  }
370
407
 
371
- pub fn backward_fill(&self, limit: FillNullLimit) -> Self {
372
- self.inner.clone().backward_fill(limit).into()
373
- }
374
-
375
- pub fn forward_fill(&self, limit: FillNullLimit) -> Self {
376
- self.inner.clone().forward_fill(limit).into()
377
- }
378
-
379
408
  pub fn shift(&self, n: &Self, fill_value: Option<&Self>) -> Self {
380
409
  let expr = self.inner.clone();
381
410
  let out = match fill_value {
@@ -394,16 +423,8 @@ impl RbExpr {
394
423
  strategy: String,
395
424
  limit: FillNullLimit,
396
425
  ) -> RbResult<Self> {
397
- let strat = parse_fill_null_strategy(&strategy, limit)?;
398
- Ok(self
399
- .inner
400
- .clone()
401
- .apply(
402
- move |s| s.fill_null(strat).map(Some),
403
- GetOutput::same_type(),
404
- )
405
- .with_fmt("fill_null_with_strategy")
406
- .into())
426
+ let strategy = parse_fill_null_strategy(&strategy, limit)?;
427
+ Ok(self.inner.clone().fill_null_with_strategy(strategy).into())
407
428
  }
408
429
 
409
430
  pub fn fill_nan(&self, expr: &Self) -> Self {
@@ -445,6 +466,13 @@ impl RbExpr {
445
466
  .into()
446
467
  }
447
468
 
469
+ pub fn is_close(&self, other: &Self, abs_tol: f64, rel_tol: f64, nans_equal: bool) -> Self {
470
+ self.inner
471
+ .clone()
472
+ .is_close(other.inner.clone(), abs_tol, rel_tol, nans_equal)
473
+ .into()
474
+ }
475
+
448
476
  pub fn approx_n_unique(&self) -> Self {
449
477
  self.inner.clone().approx_n_unique().into()
450
478
  }
@@ -457,8 +485,14 @@ impl RbExpr {
457
485
  self.inner.clone().is_last_distinct().into()
458
486
  }
459
487
 
460
- pub fn explode(&self) -> Self {
461
- self.inner.clone().explode().into()
488
+ pub fn explode(&self, empty_as_null: bool, keep_nulls: bool) -> Self {
489
+ self.inner
490
+ .clone()
491
+ .explode(ExplodeOptions {
492
+ empty_as_null,
493
+ keep_nulls,
494
+ })
495
+ .into()
462
496
  }
463
497
 
464
498
  pub fn gather_every(&self, n: usize, offset: usize) -> Self {
@@ -488,14 +522,19 @@ impl RbExpr {
488
522
  }
489
523
 
490
524
  pub fn rechunk(&self) -> Self {
491
- self.inner
492
- .clone()
493
- .map(|s| Ok(Some(s.rechunk())), GetOutput::same_type())
494
- .into()
525
+ self.inner.clone().rechunk().into()
526
+ }
527
+
528
+ pub fn round(&self, decimals: u32, mode: Wrap<RoundMode>) -> Self {
529
+ self.inner.clone().round(decimals, mode.0).into()
495
530
  }
496
531
 
497
- pub fn round(&self, decimals: u32) -> Self {
498
- self.inner.clone().round(decimals).into()
532
+ pub fn round_sig_figs(&self, digits: i32) -> Self {
533
+ self.clone().inner.round_sig_figs(digits).into()
534
+ }
535
+
536
+ pub fn truncate(&self, decimals: u32) -> Self {
537
+ self.inner.clone().truncate(decimals).into()
499
538
  }
500
539
 
501
540
  pub fn floor(&self) -> Self {
@@ -533,6 +572,10 @@ impl RbExpr {
533
572
  self.inner.clone().tan().into()
534
573
  }
535
574
 
575
+ pub fn cot(&self) -> Self {
576
+ self.inner.clone().cot().into()
577
+ }
578
+
536
579
  pub fn arcsin(&self) -> Self {
537
580
  self.inner.clone().arcsin().into()
538
581
  }
@@ -569,6 +612,14 @@ impl RbExpr {
569
612
  self.inner.clone().arctanh().into()
570
613
  }
571
614
 
615
+ pub fn degrees(&self) -> Self {
616
+ self.inner.clone().degrees().into()
617
+ }
618
+
619
+ pub fn radians(&self) -> Self {
620
+ self.inner.clone().radians().into()
621
+ }
622
+
572
623
  pub fn sign(&self) -> Self {
573
624
  self.inner.clone().sign().into()
574
625
  }
@@ -577,25 +628,70 @@ impl RbExpr {
577
628
  self.inner.clone().is_duplicated().into()
578
629
  }
579
630
 
580
- pub fn over(&self, partition_by: RArray) -> RbResult<Self> {
581
- let partition_by = rb_exprs_to_exprs(partition_by)?;
582
- Ok(self.inner.clone().over(partition_by).into())
631
+ pub fn over(
632
+ &self,
633
+ partition_by: Option<RArray>,
634
+ order_by: Option<RArray>,
635
+ order_by_descending: bool,
636
+ order_by_nulls_last: bool,
637
+ mapping_strategy: Wrap<WindowMapping>,
638
+ ) -> RbResult<Self> {
639
+ let partition_by = partition_by.map(|v| v.to_exprs()).transpose()?;
640
+
641
+ let order_by = order_by.map(|v| v.to_exprs()).transpose()?.map(|order_by| {
642
+ (
643
+ order_by,
644
+ SortOptions {
645
+ descending: order_by_descending,
646
+ nulls_last: order_by_nulls_last,
647
+ ..Default::default()
648
+ },
649
+ )
650
+ });
651
+
652
+ Ok(self
653
+ .inner
654
+ .clone()
655
+ .over_with_options(partition_by, order_by, mapping_strategy.0)
656
+ .map_err(RbPolarsErr::from)?
657
+ .into())
658
+ }
659
+
660
+ pub fn rolling(
661
+ &self,
662
+ index_column: &RbExpr,
663
+ period: String,
664
+ offset: String,
665
+ closed: Wrap<ClosedWindow>,
666
+ ) -> RbResult<Self> {
667
+ let period = Duration::try_parse(&period).map_err(RbPolarsErr::from)?;
668
+ let offset = Duration::try_parse(&offset).map_err(RbPolarsErr::from)?;
669
+ let closed = closed.0;
670
+
671
+ Ok(self
672
+ .inner
673
+ .clone()
674
+ .rolling(index_column.inner.clone(), period, offset, closed)
675
+ .into())
583
676
  }
584
677
 
585
- pub fn _and(&self, expr: &Self) -> Self {
678
+ pub fn and_(&self, expr: &Self) -> Self {
586
679
  self.inner.clone().and(expr.inner.clone()).into()
587
680
  }
588
681
 
589
- pub fn _xor(&self, expr: &Self) -> Self {
590
- self.inner.clone().xor(expr.inner.clone()).into()
682
+ pub fn or_(&self, expr: &Self) -> Self {
683
+ self.inner.clone().or(expr.inner.clone()).into()
591
684
  }
592
685
 
593
- pub fn _or(&self, expr: &Self) -> Self {
594
- self.inner.clone().or(expr.inner.clone()).into()
686
+ pub fn xor_(&self, expr: &Self) -> Self {
687
+ self.inner.clone().xor(expr.inner.clone()).into()
595
688
  }
596
689
 
597
- pub fn is_in(&self, expr: &Self) -> Self {
598
- self.inner.clone().is_in(expr.inner.clone()).into()
690
+ pub fn is_in(&self, expr: &Self, nulls_equal: bool) -> Self {
691
+ self.inner
692
+ .clone()
693
+ .is_in(expr.inner.clone(), nulls_equal)
694
+ .into()
599
695
  }
600
696
 
601
697
  pub fn repeat_by(&self, by: &Self) -> Self {
@@ -606,6 +702,14 @@ impl RbExpr {
606
702
  self.inner.clone().pow(exponent.inner.clone()).into()
607
703
  }
608
704
 
705
+ pub fn sqrt(&self) -> Self {
706
+ self.inner.clone().sqrt().into()
707
+ }
708
+
709
+ pub fn cbrt(&self) -> Self {
710
+ self.inner.clone().cbrt().into()
711
+ }
712
+
609
713
  pub fn cum_sum(&self, reverse: bool) -> Self {
610
714
  self.inner.clone().cum_sum(reverse).into()
611
715
  }
@@ -626,48 +730,29 @@ impl RbExpr {
626
730
  self.inner.clone().product().into()
627
731
  }
628
732
 
629
- pub fn shrink_dtype(&self) -> Self {
630
- self.inner.clone().shrink_dtype().into()
631
- }
632
-
633
- pub fn map_batches(
634
- &self,
635
- lambda: Value,
636
- output_type: Option<Wrap<DataType>>,
637
- agg_list: bool,
638
- is_elementwise: bool,
639
- returns_scalar: bool,
640
- ) -> Self {
641
- map_single(
642
- self,
643
- lambda,
644
- output_type,
645
- agg_list,
646
- is_elementwise,
647
- returns_scalar,
648
- )
649
- }
650
-
651
733
  pub fn dot(&self, other: &Self) -> Self {
652
734
  self.inner.clone().dot(other.inner.clone()).into()
653
735
  }
654
736
 
655
- pub fn reinterpret(&self, signed: bool) -> Self {
656
- self.inner.clone().reinterpret(signed).into()
657
- }
658
-
659
- pub fn mode(&self) -> Self {
660
- self.inner.clone().mode().into()
737
+ pub fn reinterpret(&self, signed: Option<bool>, dtype: Option<RbDataType>) -> Self {
738
+ self.inner
739
+ .clone()
740
+ .reinterpret(signed, dtype.map(|dt| dt.0))
741
+ .into()
661
742
  }
662
743
 
663
- pub fn exclude(&self, columns: Vec<String>) -> Self {
664
- self.inner.clone().exclude(columns).into()
744
+ pub fn mode(&self, maintain_order: bool) -> Self {
745
+ self.inner.clone().mode(maintain_order).into()
665
746
  }
666
747
 
667
748
  pub fn interpolate(&self, method: Wrap<InterpolationMethod>) -> Self {
668
749
  self.inner.clone().interpolate(method.0).into()
669
750
  }
670
751
 
752
+ pub fn interpolate_by(&self, by: &Self) -> Self {
753
+ self.inner.clone().interpolate_by(by.inner.clone()).into()
754
+ }
755
+
671
756
  pub fn lower_bound(&self) -> Self {
672
757
  self.inner.clone().lower_bound().into()
673
758
  }
@@ -676,10 +761,10 @@ impl RbExpr {
676
761
  self.inner.clone().upper_bound().into()
677
762
  }
678
763
 
679
- pub fn cumulative_eval(&self, expr: &Self, min_periods: usize, parallel: bool) -> Self {
764
+ pub fn cumulative_eval(&self, expr: &Self, min_samples: usize) -> Self {
680
765
  self.inner
681
766
  .clone()
682
- .cumulative_eval(expr.inner.clone(), min_periods, parallel)
767
+ .cumulative_eval(expr.inner.clone(), min_samples)
683
768
  .into()
684
769
  }
685
770
 
@@ -691,8 +776,11 @@ impl RbExpr {
691
776
  self.inner.clone().rank(options, seed).into()
692
777
  }
693
778
 
694
- pub fn diff(&self, n: i64, null_behavior: Wrap<NullBehavior>) -> Self {
695
- self.inner.clone().diff(n, null_behavior.0).into()
779
+ pub fn diff(&self, n: &Self, null_behavior: Wrap<NullBehavior>) -> Self {
780
+ self.inner
781
+ .clone()
782
+ .diff(n.inner.clone(), null_behavior.0)
783
+ .into()
696
784
  }
697
785
 
698
786
  pub fn pct_change(&self, n: &Self) -> Self {
@@ -766,6 +854,15 @@ impl RbExpr {
766
854
  self.inner.clone().ewm_mean(options).into()
767
855
  }
768
856
 
857
+ pub fn ewm_mean_by(&self, times: &RbExpr, half_life: String) -> RbResult<Self> {
858
+ let half_life = Duration::try_parse(&half_life).map_err(RbPolarsErr::from)?;
859
+ Ok(self
860
+ .inner
861
+ .clone()
862
+ .ewm_mean_by(times.inner.clone(), half_life)
863
+ .into())
864
+ }
865
+
769
866
  pub fn ewm_std(
770
867
  &self,
771
868
  alpha: f64,
@@ -802,20 +899,10 @@ impl RbExpr {
802
899
  self.inner.clone().ewm_var(options).into()
803
900
  }
804
901
 
805
- pub fn extend_constant(&self, value: Wrap<AnyValue>, n: usize) -> Self {
806
- let value = value.into_value();
807
- let value = Opaque::from(value);
902
+ pub fn extend_constant(&self, value: &Self, n: &Self) -> Self {
808
903
  self.inner
809
904
  .clone()
810
- .apply(
811
- move |s| {
812
- let value = Ruby::get().unwrap().get_inner(value);
813
- let value = Wrap::<AnyValue>::try_convert(value).unwrap().0;
814
- s.extend_constant(value, n).map(Some)
815
- },
816
- GetOutput::same_type(),
817
- )
818
- .with_fmt("extend")
905
+ .extend_constant(value.inner.clone(), n.inner.clone())
819
906
  .into()
820
907
  }
821
908
 
@@ -827,8 +914,16 @@ impl RbExpr {
827
914
  self.inner.clone().all(drop_nulls).into()
828
915
  }
829
916
 
830
- pub fn log(&self, base: f64) -> Self {
831
- self.inner.clone().log(base).into()
917
+ pub fn is_empty(&self, ignore_nulls: bool) -> Self {
918
+ self.inner.clone().is_empty(ignore_nulls).into()
919
+ }
920
+
921
+ pub fn log(&self, base: &RbExpr) -> Self {
922
+ self.inner.clone().log(base.inner.clone()).into()
923
+ }
924
+
925
+ pub fn log1p(&self) -> Self {
926
+ self.inner.clone().log1p().into()
832
927
  }
833
928
 
834
929
  pub fn exp(&self) -> Self {
@@ -843,13 +938,11 @@ impl RbExpr {
843
938
  self.inner.clone().hash(seed, seed_1, seed_2, seed_3).into()
844
939
  }
845
940
 
846
- pub fn set_sorted_flag(&self, descending: bool) -> Self {
847
- let is_sorted = if descending {
848
- IsSorted::Descending
849
- } else {
850
- IsSorted::Ascending
851
- };
852
- self.inner.clone().set_sorted_flag(is_sorted).into()
941
+ pub fn set_sorted_flag(&self, descending: bool, nulls_last: bool) -> Self {
942
+ let sortedness = AExprSorted::default()
943
+ .with_desc(Some(descending))
944
+ .with_nulls_last(Some(nulls_last));
945
+ self.inner.clone().set_sorted_flag(sortedness).into()
853
946
  }
854
947
 
855
948
  pub fn replace(&self, old: &Self, new: &Self) -> Self {
@@ -876,4 +969,35 @@ impl RbExpr {
876
969
  )
877
970
  .into()
878
971
  }
972
+
973
+ pub fn hist(
974
+ &self,
975
+ bins: Option<&RbExpr>,
976
+ bin_count: Option<usize>,
977
+ include_category: bool,
978
+ include_breakpoint: bool,
979
+ ) -> Self {
980
+ let bins = bins.map(|e| e.inner.clone());
981
+ self.inner
982
+ .clone()
983
+ .hist(bins, bin_count, include_category, include_breakpoint)
984
+ .into()
985
+ }
986
+
987
+ #[allow(clippy::wrong_self_convention)]
988
+ pub fn into_selector(&self) -> RbResult<RbSelector> {
989
+ Ok(self
990
+ .inner
991
+ .clone()
992
+ .into_selector()
993
+ .ok_or_else(
994
+ || polars_err!(InvalidOperation: "expr `{}` is not a selector", &self.inner),
995
+ )
996
+ .map_err(RbPolarsErr::from)?
997
+ .into())
998
+ }
999
+
1000
+ pub fn new_selector(selector: &RbSelector) -> Self {
1001
+ Expr::Selector(selector.inner.clone()).into()
1002
+ }
879
1003
  }