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
@@ -0,0 +1,113 @@
1
+ use std::sync::Arc;
2
+
3
+ use magnus::{TryConvert, Value, value::ReprValue};
4
+ use polars::prelude::default_values::DefaultFieldValues;
5
+ use polars::prelude::deletion::DeletionFilesList;
6
+ use polars::prelude::{
7
+ CastColumnsPolicy, CloudScheme, ColumnMapping, ExtraColumnsPolicy, MissingColumnsPolicy,
8
+ PlSmallStr, Schema, TableStatistics, UnifiedScanArgs,
9
+ };
10
+ use polars_io::{HiveOptions, RowIndex};
11
+ use polars_utils::IdxSize;
12
+ use polars_utils::slice_enum::Slice;
13
+
14
+ use crate::io::cloud_options::OptRbCloudOptions;
15
+ use crate::prelude::Wrap;
16
+ use crate::{RbDataFrame, RbResult};
17
+
18
+ /// Interface to `class ScanOptions` on the Ruby side
19
+ pub struct RbScanOptions(Value);
20
+
21
+ impl TryConvert for RbScanOptions {
22
+ fn try_convert(ob: Value) -> RbResult<Self> {
23
+ Ok(Self(ob))
24
+ }
25
+ }
26
+
27
+ impl TryConvert for Wrap<TableStatistics> {
28
+ fn try_convert(ob: Value) -> RbResult<Self> {
29
+ let attr: Value = ob.funcall("_df", ())?;
30
+ Ok(Wrap(TableStatistics(Arc::new(
31
+ <&RbDataFrame>::try_convert(attr)?.clone().df.into_inner(),
32
+ ))))
33
+ }
34
+ }
35
+
36
+ impl RbScanOptions {
37
+ pub fn extract_unified_scan_args(
38
+ &self,
39
+ // For cloud_options init
40
+ cloud_scheme: Option<CloudScheme>,
41
+ ) -> RbResult<UnifiedScanArgs> {
42
+ let row_index: Option<(Wrap<PlSmallStr>, IdxSize)> = self.0.funcall("row_index", ())?;
43
+ let pre_slice: Option<(i64, usize)> = self.0.funcall("pre_slice", ())?;
44
+ let cast_options: Wrap<CastColumnsPolicy> = self.0.funcall("cast_options", ())?;
45
+ let extra_columns: Wrap<ExtraColumnsPolicy> = self.0.funcall("extra_columns", ())?;
46
+ let missing_columns: Wrap<MissingColumnsPolicy> = self.0.funcall("missing_columns", ())?;
47
+ let include_file_paths: Option<Wrap<PlSmallStr>> =
48
+ self.0.funcall("include_file_paths", ())?;
49
+ let glob: bool = self.0.funcall("glob", ())?;
50
+ let hidden_file_prefix: Option<Vec<String>> = self.0.funcall("hidden_file_prefix", ())?;
51
+ let column_mapping: Option<Wrap<ColumnMapping>> = self.0.funcall("column_mapping", ())?;
52
+ let default_values: Option<Wrap<DefaultFieldValues>> =
53
+ self.0.funcall("default_values", ())?;
54
+ let hive_partitioning: Option<bool> = self.0.funcall("hive_partitioning", ())?;
55
+ let hive_schema: Option<Wrap<Schema>> = self.0.funcall("hive_schema", ())?;
56
+ let try_parse_hive_dates: bool = self.0.funcall("try_parse_hive_dates", ())?;
57
+ let rechunk: bool = self.0.funcall("rechunk", ())?;
58
+ let cache: bool = self.0.funcall("cache", ())?;
59
+ let storage_options: OptRbCloudOptions = self.0.funcall("storage_options", ())?;
60
+ let credential_provider: Option<Value> = self.0.funcall("credential_provider", ())?;
61
+ let deletion_files: Option<Wrap<DeletionFilesList>> =
62
+ self.0.funcall("deletion_files", ())?;
63
+ let table_statistics: Option<Wrap<TableStatistics>> =
64
+ self.0.funcall("table_statistics", ())?;
65
+ let row_count: Option<(u64, u64)> = self.0.funcall("row_count", ())?;
66
+
67
+ let cloud_options =
68
+ storage_options.extract_opt_cloud_options(cloud_scheme, credential_provider)?;
69
+
70
+ let hive_schema = hive_schema.map(|s| Arc::new(s.0));
71
+
72
+ let row_index = row_index.map(|(name, offset)| RowIndex {
73
+ name: name.0,
74
+ offset,
75
+ });
76
+
77
+ let hive_options = HiveOptions {
78
+ enabled: hive_partitioning,
79
+ hive_start_idx: 0,
80
+ schema: hive_schema,
81
+ try_parse_dates: try_parse_hive_dates,
82
+ };
83
+
84
+ let unified_scan_args = UnifiedScanArgs {
85
+ // Schema is currently still stored inside the options per scan type, but we do eventually
86
+ // want to put it here instead.
87
+ schema: None,
88
+ cloud_options,
89
+ hive_options,
90
+ rechunk,
91
+ cache,
92
+ glob,
93
+ hidden_file_prefix: hidden_file_prefix
94
+ .map(|x| x.into_iter().map(|x| (*x).into()).collect()),
95
+ projection: None,
96
+ column_mapping: column_mapping.map(|x| x.0),
97
+ default_values: default_values
98
+ .map(|x| x.0)
99
+ .filter(|DefaultFieldValues::Iceberg(v)| !v.is_empty()),
100
+ row_index,
101
+ pre_slice: pre_slice.map(Slice::from),
102
+ cast_columns_policy: cast_options.0,
103
+ missing_columns_policy: missing_columns.0,
104
+ extra_columns_policy: extra_columns.0,
105
+ include_file_paths: include_file_paths.map(|x| x.0),
106
+ deletion_files: DeletionFilesList::filter_empty(deletion_files.map(|x| x.0)),
107
+ table_statistics: table_statistics.map(|x| x.0),
108
+ row_count,
109
+ };
110
+
111
+ Ok(unified_scan_args)
112
+ }
113
+ }
@@ -0,0 +1,46 @@
1
+ use std::sync::Arc;
2
+
3
+ use magnus::{TryConvert, Value, value::ReprValue};
4
+ use polars::prelude::sync_on_close::SyncOnCloseType;
5
+ use polars::prelude::{CloudScheme, UnifiedSinkArgs};
6
+
7
+ use crate::io::cloud_options::OptRbCloudOptions;
8
+ use crate::{RbResult, Wrap};
9
+
10
+ /// Interface to `class SinkOptions` on the Ruby side
11
+ pub struct RbSinkOptions(Value);
12
+
13
+ impl TryConvert for RbSinkOptions {
14
+ fn try_convert(ob: Value) -> RbResult<Self> {
15
+ Ok(Self(ob))
16
+ }
17
+ }
18
+
19
+ impl RbSinkOptions {
20
+ pub fn extract_unified_sink_args(
21
+ &self,
22
+ cloud_scheme: Option<CloudScheme>,
23
+ ) -> RbResult<UnifiedSinkArgs> {
24
+ let mkdir: bool = self.0.funcall("mkdir", ())?;
25
+ let maintain_order: bool = self.0.funcall("maintain_order", ())?;
26
+ let sync_on_close: Option<Wrap<SyncOnCloseType>> = self.0.funcall("sync_on_close", ())?;
27
+ let storage_options: OptRbCloudOptions = self.0.funcall("storage_options", ())?;
28
+ let credential_provider: Option<Value> = self.0.funcall("credential_provider", ())?;
29
+ let sinked_paths_callback: Option<Value> = self.0.funcall("sinked_paths_callback", ())?;
30
+
31
+ let cloud_options =
32
+ storage_options.extract_opt_cloud_options(cloud_scheme, credential_provider)?;
33
+
34
+ let sync_on_close = sync_on_close.map_or(SyncOnCloseType::default(), |x| x.0);
35
+
36
+ let unified_sink_args = UnifiedSinkArgs {
37
+ mkdir,
38
+ maintain_order,
39
+ sync_on_close,
40
+ cloud_options: cloud_options.map(Arc::new),
41
+ sinked_paths_callback: sinked_paths_callback.map(|_| todo!()),
42
+ };
43
+
44
+ Ok(unified_sink_args)
45
+ }
46
+ }
@@ -0,0 +1,21 @@
1
+ use magnus::{TryConvert, Value};
2
+ use polars::prelude::SinkDestination;
3
+
4
+ use crate::RbResult;
5
+ use crate::prelude::Wrap;
6
+
7
+ pub struct RbFileSinkDestination(Value);
8
+
9
+ impl TryConvert for RbFileSinkDestination {
10
+ fn try_convert(ob: Value) -> RbResult<Self> {
11
+ Ok(Self(ob))
12
+ }
13
+ }
14
+
15
+ impl RbFileSinkDestination {
16
+ pub fn extract_file_sink_destination(&self) -> RbResult<SinkDestination> {
17
+ let v = Wrap::<polars_plan::dsl::SinkTarget>::try_convert(self.0)?;
18
+
19
+ Ok(SinkDestination::File { target: v.0 })
20
+ }
21
+ }
@@ -0,0 +1,39 @@
1
+ use magnus::Ruby;
2
+ use polars::prelude::*;
3
+
4
+ use super::RbLazyFrame;
5
+ use crate::utils::EnterPolarsExt;
6
+ use crate::{RbDataFrame, RbResult};
7
+
8
+ impl RbLazyFrame {
9
+ pub fn collect_concurrently(ruby: &Ruby, self_: &Self) -> RbResult<RbInProcessQuery> {
10
+ let ipq = ruby.enter_polars(|| {
11
+ let ldf = self_.ldf.read().clone();
12
+ ldf.collect_concurrently()
13
+ })?;
14
+ Ok(RbInProcessQuery { ipq })
15
+ }
16
+ }
17
+
18
+ #[magnus::wrap(class = "Polars::RbInProcessQuery")]
19
+ #[repr(transparent)]
20
+ #[derive(Clone)]
21
+ pub struct RbInProcessQuery {
22
+ pub ipq: InProcessQuery,
23
+ }
24
+
25
+ impl RbInProcessQuery {
26
+ pub fn cancel(ruby: &Ruby, self_: &Self) -> RbResult<()> {
27
+ ruby.enter_polars_ok(|| self_.ipq.cancel())
28
+ }
29
+
30
+ pub fn fetch(ruby: &Ruby, self_: &Self) -> RbResult<Option<RbDataFrame>> {
31
+ let out = ruby.enter_polars(|| self_.ipq.fetch().transpose())?;
32
+ Ok(out.map(|df| df.into()))
33
+ }
34
+
35
+ pub fn fetch_blocking(ruby: &Ruby, self_: &Self) -> RbResult<RbDataFrame> {
36
+ let out = ruby.enter_polars(|| self_.ipq.fetch_blocking())?;
37
+ Ok(out.into())
38
+ }
39
+ }