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,5 +1,5 @@
1
- use magnus::{prelude::*, r_hash::ForEach, RArray, RHash, Symbol, Value};
2
- use polars::frame::row::{rows_to_schema_supertypes, rows_to_supertypes, Row};
1
+ use magnus::{RArray, RHash, Ruby, Symbol, Value, prelude::*, r_hash::ForEach};
2
+ use polars::frame::row::{Row, rows_to_schema_supertypes, rows_to_supertypes};
3
3
  use polars::prelude::*;
4
4
 
5
5
  use super::*;
@@ -54,7 +54,7 @@ fn finish_from_rows(
54
54
  schema_overrides: Option<Schema>,
55
55
  infer_schema_length: Option<usize>,
56
56
  ) -> RbResult<RbDataFrame> {
57
- let mut schema = if let Some(mut schema) = schema {
57
+ let schema = if let Some(mut schema) = schema {
58
58
  resolve_schema_overrides(&mut schema, schema_overrides);
59
59
  update_schema_from_rows(&mut schema, &rows, infer_schema_length)?;
60
60
  schema
@@ -62,11 +62,6 @@ fn finish_from_rows(
62
62
  rows_to_schema_supertypes(&rows, infer_schema_length).map_err(RbPolarsErr::from)?
63
63
  };
64
64
 
65
- // TODO: Remove this step when Decimals are supported properly.
66
- // Erasing the decimal precision/scale here will just require us to infer it again later.
67
- // https://github.com/pola-rs/polars/issues/14427
68
- erase_decimal_precision_scale(&mut schema);
69
-
70
65
  let df = DataFrame::from_rows_and_schema(&rows, &schema).map_err(RbPolarsErr::from)?;
71
66
  Ok(df.into())
72
67
  }
@@ -106,14 +101,6 @@ fn resolve_schema_overrides(schema: &mut Schema, schema_overrides: Option<Schema
106
101
  }
107
102
  }
108
103
 
109
- fn erase_decimal_precision_scale(schema: &mut Schema) {
110
- for dtype in schema.iter_values_mut() {
111
- if let DataType::Decimal(_, _) = dtype {
112
- *dtype = DataType::Decimal(None, None)
113
- }
114
- }
115
- }
116
-
117
104
  fn columns_names_to_empty_schema<'a, I>(column_names: I) -> Schema
118
105
  where
119
106
  I: IntoIterator<Item = &'a str>,
@@ -125,6 +112,7 @@ where
125
112
  }
126
113
 
127
114
  fn dicts_to_rows<'a>(data: &Value, names: &'a [String], _strict: bool) -> RbResult<Vec<Row<'a>>> {
115
+ let ruby = Ruby::get_with(*data);
128
116
  let (data, len) = get_rbseq(*data)?;
129
117
  let mut rows = Vec::with_capacity(len);
130
118
  for d in data.into_iter() {
@@ -132,8 +120,8 @@ fn dicts_to_rows<'a>(data: &Value, names: &'a [String], _strict: bool) -> RbResu
132
120
 
133
121
  let mut row = Vec::with_capacity(names.len());
134
122
  for k in names.iter() {
135
- // TODO improve performance
136
- let val = match d.get(k.clone()).or_else(|| d.get(Symbol::new(k))) {
123
+ // TODO improve performance (must work with GC)
124
+ let val = match d.get(k.clone()).or_else(|| d.get(ruby.to_symbol(k))) {
137
125
  None => AnyValue::Null,
138
126
  Some(val) => Wrap::<AnyValue>::try_convert(val)?.0,
139
127
  };
@@ -1,55 +1,46 @@
1
- use magnus::{prelude::*, IntoValue, RArray, Value};
1
+ use magnus::{Ruby, Value, prelude::*};
2
2
 
3
3
  use super::*;
4
- use crate::conversion::{ObjectValue, Wrap};
5
- use crate::interop::arrow::to_ruby::dataframe_to_stream;
6
4
  use crate::RbResult;
5
+ use crate::conversion::{ObjectValue, Wrap};
6
+ use crate::interop::arrow::to_rb::dataframe_to_stream;
7
+ use crate::ruby::utils::TryIntoValue;
7
8
 
8
9
  impl RbDataFrame {
9
- pub fn row_tuple(&self, idx: i64) -> Value {
10
+ pub fn row_tuple(ruby: &Ruby, self_: &Self, idx: i64) -> RbResult<Value> {
10
11
  let idx = if idx < 0 {
11
- (self.df.borrow().height() as i64 + idx) as usize
12
+ (self_.df.read().height() as i64 + idx) as usize
12
13
  } else {
13
14
  idx as usize
14
15
  };
15
- RArray::from_iter(
16
- self.df
17
- .borrow()
18
- .get_columns()
19
- .iter()
20
- .map(|s| match s.dtype() {
21
- DataType::Object(_, _) => {
22
- let obj: Option<&ObjectValue> = s.get_object(idx).map(|any| any.into());
23
- obj.unwrap().to_value()
24
- }
25
- _ => Wrap(s.get(idx).unwrap()).into_value(),
26
- }),
27
- )
28
- .as_value()
16
+ ruby.ary_try_from_iter(self_.df.read().columns().iter().map(|s| match s.dtype() {
17
+ DataType::Object(_) => {
18
+ let obj: Option<&ObjectValue> = s.get_object(idx).map(|any| any.into());
19
+ // TODO remove unwrap and clone
20
+ obj.unwrap().clone().try_into_value_with(ruby)
21
+ }
22
+ _ => Wrap(s.get(idx).unwrap()).try_into_value_with(ruby),
23
+ }))
24
+ .map(|v| v.as_value())
29
25
  }
30
26
 
31
- pub fn row_tuples(&self) -> Value {
32
- let df = &self.df;
33
- RArray::from_iter((0..df.borrow().height()).map(|idx| {
34
- RArray::from_iter(
35
- self.df
36
- .borrow()
37
- .get_columns()
38
- .iter()
39
- .map(|s| match s.dtype() {
40
- DataType::Object(_, _) => {
41
- let obj: Option<&ObjectValue> = s.get_object(idx).map(|any| any.into());
42
- obj.unwrap().to_value()
43
- }
44
- _ => Wrap(s.get(idx).unwrap()).into_value(),
45
- }),
46
- )
27
+ pub fn row_tuples(ruby: &Ruby, self_: &Self) -> RbResult<Value> {
28
+ let df = &self_.df;
29
+ ruby.ary_try_from_iter((0..df.read().height()).map(|idx| {
30
+ ruby.ary_try_from_iter(self_.df.read().columns().iter().map(|s| match s.dtype() {
31
+ DataType::Object(_) => {
32
+ let obj: Option<&ObjectValue> = s.get_object(idx).map(|any| any.into());
33
+ // TODO remove unwrap and clone
34
+ obj.unwrap().clone().try_into_value_with(ruby)
35
+ }
36
+ _ => Wrap(s.get(idx).unwrap()).try_into_value_with(ruby),
37
+ }))
47
38
  }))
48
- .as_value()
39
+ .map(|v| v.as_value())
49
40
  }
50
41
 
51
- pub fn __arrow_c_stream__(&self) -> RbResult<Value> {
52
- self.df.borrow_mut().align_chunks();
53
- dataframe_to_stream(&self.df.borrow())
42
+ pub fn __arrow_c_stream__(ruby: &Ruby, self_: &Self) -> RbResult<Value> {
43
+ self_.df.write().align_chunks();
44
+ dataframe_to_stream(&self_.df.read(), ruby)
54
45
  }
55
46
  }