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,38 +1,45 @@
1
+ use magnus::Value;
1
2
  use polars::prelude::*;
2
3
 
3
- use crate::RbExpr;
4
+ use crate::ruby::plan_callback::PlanCallbackExt;
5
+ use crate::ruby::ruby_function::RubyObject;
6
+ use crate::{RbExpr, RbPolarsErr, RbResult};
4
7
 
5
8
  impl RbExpr {
6
- pub fn array_max(&self) -> Self {
9
+ pub fn arr_len(&self) -> Self {
10
+ self.inner.clone().arr().len().into()
11
+ }
12
+
13
+ pub fn arr_max(&self) -> Self {
7
14
  self.inner.clone().arr().max().into()
8
15
  }
9
16
 
10
- pub fn array_min(&self) -> Self {
17
+ pub fn arr_min(&self) -> Self {
11
18
  self.inner.clone().arr().min().into()
12
19
  }
13
20
 
14
- pub fn array_sum(&self) -> Self {
21
+ pub fn arr_sum(&self) -> Self {
15
22
  self.inner.clone().arr().sum().into()
16
23
  }
17
24
 
18
- pub fn arr_unique(&self, maintain_order: bool) -> Self {
19
- if maintain_order {
20
- self.inner.clone().arr().unique_stable().into()
21
- } else {
22
- self.inner.clone().arr().unique().into()
23
- }
25
+ pub fn arr_std(&self, ddof: u8) -> Self {
26
+ self.inner.clone().arr().std(ddof).into()
24
27
  }
25
28
 
26
- pub fn arr_to_list(&self) -> Self {
27
- self.inner.clone().arr().to_list().into()
29
+ pub fn arr_var(&self, ddof: u8) -> Self {
30
+ self.inner.clone().arr().var(ddof).into()
31
+ }
32
+
33
+ pub fn arr_mean(&self) -> Self {
34
+ self.inner.clone().arr().mean().into()
28
35
  }
29
36
 
30
- pub fn arr_all(&self) -> Self {
31
- self.inner.clone().arr().all().into()
37
+ pub fn arr_median(&self) -> Self {
38
+ self.inner.clone().arr().median().into()
32
39
  }
33
40
 
34
- pub fn arr_any(&self) -> Self {
35
- self.inner.clone().arr().any().into()
41
+ pub fn arr_to_list(&self) -> Self {
42
+ self.inner.clone().arr().to_list().into()
36
43
  }
37
44
 
38
45
  pub fn arr_sort(&self, descending: bool, nulls_last: bool) -> Self {
@@ -47,10 +54,6 @@ impl RbExpr {
47
54
  .into()
48
55
  }
49
56
 
50
- pub fn arr_reverse(&self) -> Self {
51
- self.inner.clone().arr().reverse().into()
52
- }
53
-
54
57
  pub fn arr_arg_min(&self) -> Self {
55
58
  self.inner.clone().arr().arg_min().into()
56
59
  }
@@ -75,11 +78,11 @@ impl RbExpr {
75
78
  .into()
76
79
  }
77
80
 
78
- pub fn arr_contains(&self, other: &RbExpr) -> Self {
81
+ pub fn arr_contains(&self, other: &RbExpr, nulls_equal: bool) -> Self {
79
82
  self.inner
80
83
  .clone()
81
84
  .arr()
82
- .contains(other.inner.clone())
85
+ .contains(other.inner.clone(), nulls_equal)
83
86
  .into()
84
87
  }
85
88
 
@@ -90,4 +93,65 @@ impl RbExpr {
90
93
  .count_matches(expr.inner.clone())
91
94
  .into()
92
95
  }
96
+
97
+ pub fn arr_to_struct(&self, name_gen: Option<Value>) -> Self {
98
+ let name_gen = name_gen.map(|o| PlanCallback::new_ruby(RubyObject::from(o)));
99
+ self.inner.clone().arr().to_struct(name_gen).into()
100
+ }
101
+
102
+ pub fn arr_slice(
103
+ &self,
104
+ offset: &RbExpr,
105
+ length: Option<&RbExpr>,
106
+ as_array: bool,
107
+ ) -> RbResult<Self> {
108
+ let length = match length {
109
+ Some(i) => i.inner.clone(),
110
+ None => lit(i64::MAX),
111
+ };
112
+ Ok(self
113
+ .inner
114
+ .clone()
115
+ .arr()
116
+ .slice(offset.inner.clone(), length, as_array)
117
+ .map_err(RbPolarsErr::from)?
118
+ .into())
119
+ }
120
+
121
+ pub fn arr_tail(&self, n: &RbExpr, as_array: bool) -> RbResult<Self> {
122
+ Ok(self
123
+ .inner
124
+ .clone()
125
+ .arr()
126
+ .tail(n.inner.clone(), as_array)
127
+ .map_err(RbPolarsErr::from)?
128
+ .into())
129
+ }
130
+
131
+ pub fn arr_shift(&self, n: &RbExpr) -> Self {
132
+ self.inner.clone().arr().shift(n.inner.clone()).into()
133
+ }
134
+
135
+ pub fn arr_explode(&self, empty_as_null: bool, keep_nulls: bool) -> Self {
136
+ self.inner
137
+ .clone()
138
+ .arr()
139
+ .explode(ExplodeOptions {
140
+ empty_as_null,
141
+ keep_nulls,
142
+ })
143
+ .into()
144
+ }
145
+
146
+ pub fn arr_eval(&self, expr: &RbExpr, as_list: bool) -> Self {
147
+ self.inner
148
+ .clone()
149
+ .arr()
150
+ .eval(expr.inner.clone(), as_list)
151
+ .into()
152
+ }
153
+
154
+ pub fn arr_agg(&self, expr: &RbExpr) -> Self {
155
+ self.inner.clone().arr().agg(expr.inner.clone()).into()
156
+ }
93
157
  }
@@ -1,4 +1,5 @@
1
- use crate::RbExpr;
1
+ use crate::expr::datatype::RbDataTypeExpr;
2
+ use crate::{RbExpr, RbResult};
2
3
 
3
4
  impl RbExpr {
4
5
  pub fn bin_contains(&self, lit: &RbExpr) -> Self {
@@ -40,4 +41,52 @@ impl RbExpr {
40
41
  pub fn bin_base64_encode(&self) -> Self {
41
42
  self.inner.clone().binary().base64_encode().into()
42
43
  }
44
+
45
+ pub fn bin_reinterpret(&self, dtype: &RbDataTypeExpr, kind: String) -> RbResult<Self> {
46
+ use crate::RbValueError;
47
+
48
+ let is_little_endian = match kind.to_lowercase().as_str() {
49
+ "little" => true,
50
+ "big" => false,
51
+ _ => {
52
+ return Err(RbValueError::new_err(format!(
53
+ "Invalid endianness: {kind}. Valid values are \"little\" or \"big\"."
54
+ )));
55
+ }
56
+ };
57
+ Ok(self
58
+ .inner
59
+ .clone()
60
+ .binary()
61
+ .reinterpret(dtype.inner.clone(), is_little_endian)
62
+ .into())
63
+ }
64
+
65
+ pub fn bin_size_bytes(&self) -> Self {
66
+ self.inner.clone().binary().size_bytes().into()
67
+ }
68
+
69
+ pub fn bin_slice(&self, offset: &RbExpr, length: &RbExpr) -> Self {
70
+ self.inner
71
+ .clone()
72
+ .binary()
73
+ .slice(offset.inner.clone(), length.inner.clone())
74
+ .into()
75
+ }
76
+
77
+ pub fn bin_head(&self, n: &RbExpr) -> Self {
78
+ self.inner.clone().binary().head(n.inner.clone()).into()
79
+ }
80
+
81
+ pub fn bin_tail(&self, n: &RbExpr) -> Self {
82
+ self.inner.clone().binary().tail(n.inner.clone()).into()
83
+ }
84
+
85
+ pub fn bin_get(&self, index: &RbExpr, null_on_oob: bool) -> Self {
86
+ self.inner
87
+ .clone()
88
+ .binary()
89
+ .get(index.inner.clone(), null_on_oob)
90
+ .into()
91
+ }
43
92
  }
@@ -0,0 +1,39 @@
1
+ use crate::RbExpr;
2
+
3
+ impl RbExpr {
4
+ pub fn bitwise_count_ones(&self) -> Self {
5
+ self.inner.clone().bitwise_count_ones().into()
6
+ }
7
+
8
+ pub fn bitwise_count_zeros(&self) -> Self {
9
+ self.inner.clone().bitwise_count_zeros().into()
10
+ }
11
+
12
+ pub fn bitwise_leading_ones(&self) -> Self {
13
+ self.inner.clone().bitwise_leading_ones().into()
14
+ }
15
+
16
+ pub fn bitwise_leading_zeros(&self) -> Self {
17
+ self.inner.clone().bitwise_leading_zeros().into()
18
+ }
19
+
20
+ pub fn bitwise_trailing_ones(&self) -> Self {
21
+ self.inner.clone().bitwise_trailing_ones().into()
22
+ }
23
+
24
+ pub fn bitwise_trailing_zeros(&self) -> Self {
25
+ self.inner.clone().bitwise_trailing_zeros().into()
26
+ }
27
+
28
+ pub fn bitwise_and(&self) -> Self {
29
+ self.inner.clone().bitwise_and().into()
30
+ }
31
+
32
+ pub fn bitwise_or(&self) -> Self {
33
+ self.inner.clone().bitwise_or().into()
34
+ }
35
+
36
+ pub fn bitwise_xor(&self) -> Self {
37
+ self.inner.clone().bitwise_xor().into()
38
+ }
39
+ }
@@ -4,4 +4,24 @@ impl RbExpr {
4
4
  pub fn cat_get_categories(&self) -> Self {
5
5
  self.inner.clone().cat().get_categories().into()
6
6
  }
7
+
8
+ pub fn cat_len_bytes(&self) -> Self {
9
+ self.inner.clone().cat().len_bytes().into()
10
+ }
11
+
12
+ pub fn cat_len_chars(&self) -> Self {
13
+ self.inner.clone().cat().len_chars().into()
14
+ }
15
+
16
+ pub fn cat_starts_with(&self, prefix: String) -> Self {
17
+ self.inner.clone().cat().starts_with(prefix).into()
18
+ }
19
+
20
+ pub fn cat_ends_with(&self, suffix: String) -> Self {
21
+ self.inner.clone().cat().ends_with(suffix).into()
22
+ }
23
+
24
+ pub fn cat_slice(&self, offset: i64, length: Option<usize>) -> Self {
25
+ self.inner.clone().cat().slice(offset, length).into()
26
+ }
7
27
  }
@@ -0,0 +1,51 @@
1
+ use magnus::{RArray, Ruby, TryConvert, Value};
2
+ use polars::prelude::{DataType, DataTypeExpr, PlSmallStr, Schema};
3
+
4
+ use crate::prelude::Wrap;
5
+ use crate::ruby::utils::TryIntoValue;
6
+ use crate::{RbExpr, RbPolarsErr, RbResult};
7
+
8
+ #[magnus::wrap(class = "Polars::RbDataTypeExpr")]
9
+ #[repr(transparent)]
10
+ #[derive(Clone)]
11
+ pub struct RbDataTypeExpr {
12
+ pub inner: DataTypeExpr,
13
+ }
14
+
15
+ impl From<DataTypeExpr> for RbDataTypeExpr {
16
+ fn from(expr: DataTypeExpr) -> Self {
17
+ RbDataTypeExpr { inner: expr }
18
+ }
19
+ }
20
+
21
+ impl RbDataTypeExpr {
22
+ pub fn from_dtype(datatype: Wrap<DataType>) -> Self {
23
+ DataTypeExpr::Literal(datatype.0).into()
24
+ }
25
+
26
+ pub fn of_expr(expr: &RbExpr) -> Self {
27
+ DataTypeExpr::OfExpr(Box::new(expr.inner.clone())).into()
28
+ }
29
+
30
+ pub fn self_dtype() -> Self {
31
+ DataTypeExpr::SelfDtype.into()
32
+ }
33
+
34
+ pub fn collect_dtype(ruby: &Ruby, self_: &Self, schema: Wrap<Schema>) -> RbResult<Value> {
35
+ let dtype = self_
36
+ .clone()
37
+ .inner
38
+ .into_datatype(&schema.0)
39
+ .map_err(RbPolarsErr::from)?;
40
+ Wrap(dtype).try_into_value_with(ruby)
41
+ }
42
+
43
+ pub fn struct_with_fields(rb_fields: RArray) -> RbResult<Self> {
44
+ let mut fields = Vec::new();
45
+ for v in rb_fields.into_iter() {
46
+ let (name, dt_expr) = <(String, &RbDataTypeExpr)>::try_convert(v)?;
47
+ fields.push((PlSmallStr::from_string(name), dt_expr.inner.clone()));
48
+ }
49
+ Ok(DataTypeExpr::StructWithFields(fields).into())
50
+ }
51
+ }
@@ -1,9 +1,23 @@
1
1
  use polars::prelude::*;
2
2
 
3
3
  use crate::conversion::Wrap;
4
- use crate::RbExpr;
4
+ use crate::{RbExpr, RbPolarsErr, RbResult};
5
5
 
6
6
  impl RbExpr {
7
+ pub fn dt_add_business_days(
8
+ &self,
9
+ n: &RbExpr,
10
+ week_mask: [bool; 7],
11
+ holidays: &RbExpr,
12
+ roll: Wrap<Roll>,
13
+ ) -> Self {
14
+ self.inner
15
+ .clone()
16
+ .dt()
17
+ .add_business_days(n.inner.clone(), week_mask, holidays.inner.clone(), roll.0)
18
+ .into()
19
+ }
20
+
7
21
  pub fn dt_to_string(&self, format: String) -> Self {
8
22
  self.inner.clone().dt().to_string(&format).into()
9
23
  }
@@ -12,30 +26,17 @@ impl RbExpr {
12
26
  self.inner.clone().dt().offset_by(by.inner.clone()).into()
13
27
  }
14
28
 
15
- pub fn dt_epoch_seconds(&self) -> Self {
16
- self.inner
17
- .clone()
18
- .map(
19
- |s| {
20
- s.take_materialized_series()
21
- .timestamp(TimeUnit::Milliseconds)
22
- .map(|ca| Some((ca / 1000).into_column()))
23
- },
24
- GetOutput::from_type(DataType::Int64),
25
- )
26
- .into()
27
- }
28
-
29
- pub fn dt_with_time_unit(&self, tu: Wrap<TimeUnit>) -> Self {
30
- self.inner.clone().dt().with_time_unit(tu.0).into()
31
- }
32
-
33
- pub fn dt_convert_time_zone(&self, time_zone: String) -> Self {
34
- self.inner
29
+ pub fn dt_convert_time_zone(&self, time_zone: String) -> RbResult<Self> {
30
+ Ok(self
31
+ .inner
35
32
  .clone()
36
33
  .dt()
37
- .convert_time_zone(time_zone.into())
38
- .into()
34
+ .convert_time_zone(
35
+ TimeZone::opt_try_new(Some(PlSmallStr::from(time_zone)))
36
+ .map_err(RbPolarsErr::from)?
37
+ .unwrap_or(TimeZone::UTC),
38
+ )
39
+ .into())
39
40
  }
40
41
 
41
42
  pub fn dt_cast_time_unit(&self, tu: Wrap<TimeUnit>) -> Self {
@@ -47,16 +48,18 @@ impl RbExpr {
47
48
  time_zone: Option<String>,
48
49
  ambiguous: &Self,
49
50
  non_existent: Wrap<NonExistent>,
50
- ) -> Self {
51
- self.inner
51
+ ) -> RbResult<Self> {
52
+ Ok(self
53
+ .inner
52
54
  .clone()
53
55
  .dt()
54
56
  .replace_time_zone(
55
- time_zone.map(|x| x.into()),
57
+ TimeZone::opt_try_new(time_zone.map(PlSmallStr::from_string))
58
+ .map_err(RbPolarsErr::from)?,
56
59
  ambiguous.inner.clone(),
57
60
  non_existent.0,
58
61
  )
59
- .into()
62
+ .into())
60
63
  }
61
64
 
62
65
  pub fn dt_truncate(&self, every: &Self) -> Self {
@@ -83,6 +86,33 @@ impl RbExpr {
83
86
  self.inner.clone().dt().round(every.inner.clone()).into()
84
87
  }
85
88
 
89
+ pub fn dt_replace(
90
+ &self,
91
+ year: &Self,
92
+ month: &Self,
93
+ day: &Self,
94
+ hour: &Self,
95
+ minute: &Self,
96
+ second: &Self,
97
+ microsecond: &Self,
98
+ ambiguous: &Self,
99
+ ) -> Self {
100
+ self.inner
101
+ .clone()
102
+ .dt()
103
+ .replace(
104
+ year.inner.clone(),
105
+ month.inner.clone(),
106
+ day.inner.clone(),
107
+ hour.inner.clone(),
108
+ minute.inner.clone(),
109
+ second.inner.clone(),
110
+ microsecond.inner.clone(),
111
+ ambiguous.inner.clone(),
112
+ )
113
+ .into()
114
+ }
115
+
86
116
  pub fn dt_combine(&self, time: &Self, time_unit: Wrap<TimeUnit>) -> Self {
87
117
  self.inner
88
118
  .clone()
@@ -91,10 +121,26 @@ impl RbExpr {
91
121
  .into()
92
122
  }
93
123
 
124
+ pub fn dt_millennium(&self) -> Self {
125
+ self.inner.clone().dt().millennium().into()
126
+ }
127
+
128
+ pub fn dt_century(&self) -> Self {
129
+ self.inner.clone().dt().century().into()
130
+ }
131
+
94
132
  pub fn dt_year(&self) -> Self {
95
133
  self.clone().inner.dt().year().into()
96
134
  }
97
135
 
136
+ pub fn dt_is_business_day(&self, week_mask: [bool; 7], holidays: &RbExpr) -> Self {
137
+ self.inner
138
+ .clone()
139
+ .dt()
140
+ .is_business_day(week_mask, holidays.inner.clone())
141
+ .into()
142
+ }
143
+
98
144
  pub fn dt_is_leap_year(&self) -> Self {
99
145
  self.clone().inner.dt().is_leap_year().into()
100
146
  }
@@ -111,6 +157,10 @@ impl RbExpr {
111
157
  self.clone().inner.dt().month().into()
112
158
  }
113
159
 
160
+ pub fn dt_days_in_month(&self) -> Self {
161
+ self.inner.clone().dt().days_in_month().into()
162
+ }
163
+
114
164
  pub fn dt_week(&self) -> Self {
115
165
  self.clone().inner.dt().week().into()
116
166
  }
@@ -167,31 +217,39 @@ impl RbExpr {
167
217
  self.inner.clone().dt().timestamp(tu.0).into()
168
218
  }
169
219
 
170
- pub fn dt_total_days(&self) -> Self {
171
- self.inner.clone().dt().total_days().into()
220
+ pub fn dt_total_days(&self, fractional: bool) -> Self {
221
+ self.inner.clone().dt().total_days(fractional).into()
172
222
  }
173
223
 
174
- pub fn dt_total_hours(&self) -> Self {
175
- self.inner.clone().dt().total_hours().into()
224
+ pub fn dt_total_hours(&self, fractional: bool) -> Self {
225
+ self.inner.clone().dt().total_hours(fractional).into()
176
226
  }
177
227
 
178
- pub fn dt_total_minutes(&self) -> Self {
179
- self.inner.clone().dt().total_minutes().into()
228
+ pub fn dt_total_minutes(&self, fractional: bool) -> Self {
229
+ self.inner.clone().dt().total_minutes(fractional).into()
180
230
  }
181
231
 
182
- pub fn dt_total_seconds(&self) -> Self {
183
- self.inner.clone().dt().total_seconds().into()
232
+ pub fn dt_total_seconds(&self, fractional: bool) -> Self {
233
+ self.inner.clone().dt().total_seconds(fractional).into()
184
234
  }
185
235
 
186
- pub fn dt_total_milliseconds(&self) -> Self {
187
- self.inner.clone().dt().total_milliseconds().into()
236
+ pub fn dt_total_milliseconds(&self, fractional: bool) -> Self {
237
+ self.inner
238
+ .clone()
239
+ .dt()
240
+ .total_milliseconds(fractional)
241
+ .into()
188
242
  }
189
243
 
190
- pub fn dt_total_microseconds(&self) -> Self {
191
- self.inner.clone().dt().total_microseconds().into()
244
+ pub fn dt_total_microseconds(&self, fractional: bool) -> Self {
245
+ self.inner
246
+ .clone()
247
+ .dt()
248
+ .total_microseconds(fractional)
249
+ .into()
192
250
  }
193
251
 
194
- pub fn dt_total_nanoseconds(&self) -> Self {
195
- self.inner.clone().dt().total_nanoseconds().into()
252
+ pub fn dt_total_nanoseconds(&self, fractional: bool) -> Self {
253
+ self.inner.clone().dt().total_nanoseconds(fractional).into()
196
254
  }
197
255
  }
@@ -0,0 +1,12 @@
1
+ use crate::RbExpr;
2
+ use crate::expr::datatype::RbDataTypeExpr;
3
+
4
+ impl RbExpr {
5
+ pub fn ext_storage(&self) -> Self {
6
+ self.inner.clone().ext().storage().into()
7
+ }
8
+
9
+ pub fn ext_to(&self, dtype: &RbDataTypeExpr) -> Self {
10
+ self.inner.clone().ext().to(dtype.inner.clone()).into()
11
+ }
12
+ }