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
@@ -16,7 +16,7 @@ module Polars
16
16
  #
17
17
  # @example
18
18
  # s = Polars::Series.new(
19
- # "a", [[1, 2], [4, 3]], dtype: Polars::Array.new(2, Polars::Int64)
19
+ # "a", [[1, 2], [4, 3]], dtype: Polars::Array.new(Polars::Int64, 2)
20
20
  # )
21
21
  # s.arr.min
22
22
  # # =>
@@ -36,7 +36,7 @@ module Polars
36
36
  #
37
37
  # @example
38
38
  # s = Polars::Series.new(
39
- # "a", [[1, 2], [4, 3]], dtype: Polars::Array.new(2, Polars::Int64)
39
+ # "a", [[1, 2], [4, 3]], dtype: Polars::Array.new(Polars::Int64, 2)
40
40
  # )
41
41
  # s.arr.max
42
42
  # # =>
@@ -57,7 +57,7 @@ module Polars
57
57
  # @example
58
58
  # df = Polars::DataFrame.new(
59
59
  # {"a" => [[1, 2], [4, 3]]},
60
- # schema: {"a" => Polars::Array.new(2, Polars::Int64)}
60
+ # schema: {"a" => Polars::Array.new(Polars::Int64, 2)}
61
61
  # )
62
62
  # df.select(Polars.col("a").arr.sum)
63
63
  # # =>
@@ -74,6 +74,78 @@ module Polars
74
74
  super
75
75
  end
76
76
 
77
+ # Compute the mean of the values of the sub-arrays.
78
+ #
79
+ # @return [Series]
80
+ #
81
+ # @example
82
+ # s = Polars::Series.new("a", [[1, 2], [4, 3]], dtype: Polars::Array.new(Polars::Int64, 2))
83
+ # s.arr.mean
84
+ # # =>
85
+ # # shape: (2,)
86
+ # # Series: 'a' [f64]
87
+ # # [
88
+ # # 1.5
89
+ # # 3.5
90
+ # # ]
91
+ def mean
92
+ super
93
+ end
94
+
95
+ # Compute the std of the values of the sub-arrays.
96
+ #
97
+ # @return [Series]
98
+ #
99
+ # @example
100
+ # s = Polars::Series.new("a", [[1, 2], [4, 3]], dtype: Polars::Array.new(Polars::Int64, 2))
101
+ # s.arr.std
102
+ # # =>
103
+ # # shape: (2,)
104
+ # # Series: 'a' [f64]
105
+ # # [
106
+ # # 0.707107
107
+ # # 0.707107
108
+ # # ]
109
+ def std(ddof: 1)
110
+ super
111
+ end
112
+
113
+ # Compute the var of the values of the sub-arrays.
114
+ #
115
+ # @return [Series]
116
+ #
117
+ # @example
118
+ # s = Polars::Series.new("a", [[1, 2], [4, 3]], dtype: Polars::Array.new(Polars::Int64, 2))
119
+ # s.arr.var
120
+ # # =>
121
+ # # shape: (2,)
122
+ # # Series: 'a' [f64]
123
+ # # [
124
+ # # 0.5
125
+ # # 0.5
126
+ # # ]
127
+ def var(ddof: 1)
128
+ super
129
+ end
130
+
131
+ # Compute the median of the values of the sub-arrays.
132
+ #
133
+ # @return [Series]
134
+ #
135
+ # @example
136
+ # s = Polars::Series.new("a", [[1, 2], [4, 3]], dtype: Polars::Array.new(Polars::Int64, 2))
137
+ # s.arr.median
138
+ # # =>
139
+ # # shape: (2,)
140
+ # # Series: 'a' [f64]
141
+ # # [
142
+ # # 1.5
143
+ # # 3.5
144
+ # # ]
145
+ def median
146
+ super
147
+ end
148
+
77
149
  # Get the unique/distinct values in the array.
78
150
  #
79
151
  # @param maintain_order [Boolean]
@@ -102,6 +174,24 @@ module Polars
102
174
  super
103
175
  end
104
176
 
177
+ # Count the number of unique values in every sub-arrays.
178
+ #
179
+ # @return [Series]
180
+ #
181
+ # @example
182
+ # s = Polars::Series.new("a", [[1, 2], [4, 4]], dtype: Polars::Array.new(Polars::Int64, 2))
183
+ # s.arr.n_unique
184
+ # # =>
185
+ # # shape: (2,)
186
+ # # Series: 'a' [u32]
187
+ # # [
188
+ # # 2
189
+ # # 1
190
+ # # ]
191
+ def n_unique
192
+ super
193
+ end
194
+
105
195
  # Convert an Array column into a List column with the same inner data type.
106
196
  #
107
197
  # @return [Series]
@@ -122,6 +212,13 @@ module Polars
122
212
 
123
213
  # Evaluate whether any boolean value is true for every subarray.
124
214
  #
215
+ # @param ignore_nulls [Boolean]
216
+ # * If set to `true` (default), null values are ignored. If there
217
+ # are no non-null values, the output is `false`.
218
+ # * If set to `false`, [Kleene logic](https://en.wikipedia.org/wiki/Three-valued_logic) is used to deal with nulls:
219
+ # if the column contains any null values and no `true` values,
220
+ # the output is null.
221
+ #
125
222
  # @return [Series]
126
223
  #
127
224
  # @example
@@ -140,12 +237,161 @@ module Polars
140
237
  # # false
141
238
  # # null
142
239
  # # ]
143
- def any
240
+ def any(ignore_nulls: true)
241
+ super
242
+ end
243
+
244
+ # Return the number of elements in each array.
245
+ #
246
+ # @return [Series]
247
+ #
248
+ # @example
249
+ # s = Polars::Series.new("a", [[1, 2], [4, 3]], dtype: Polars::Array.new(Polars::Int8, 2))
250
+ # s.arr.len
251
+ # # =>
252
+ # # shape: (2,)
253
+ # # Series: 'a' [u32]
254
+ # # [
255
+ # # 2
256
+ # # 2
257
+ # # ]
258
+ def len
259
+ super
260
+ end
261
+
262
+ # Slice the sub-arrays.
263
+ #
264
+ # @param offset [Integer]
265
+ # The starting index of the slice.
266
+ # @param length [Integer]
267
+ # The length of the slice.
268
+ #
269
+ # @return [Series]
270
+ #
271
+ # @example
272
+ # s = Polars::Series.new(
273
+ # [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]],
274
+ # dtype: Polars::Array.new(Polars::Int64, 6)
275
+ # )
276
+ # s.arr.slice(1)
277
+ # # =>
278
+ # # shape: (2,)
279
+ # # Series: '' [list[i64]]
280
+ # # [
281
+ # # [2, 3, … 6]
282
+ # # [8, 9, … 12]
283
+ # # ]
284
+ #
285
+ # @example
286
+ # s.arr.slice(1, 3, as_array: true)
287
+ # # =>
288
+ # # shape: (2,)
289
+ # # Series: '' [array[i64, 3]]
290
+ # # [
291
+ # # [2, 3, 4]
292
+ # # [8, 9, 10]
293
+ # # ]
294
+ #
295
+ # @example
296
+ # s.arr.slice(-2)
297
+ # # =>
298
+ # # shape: (2,)
299
+ # # Series: '' [list[i64]]
300
+ # # [
301
+ # # [5, 6]
302
+ # # [11, 12]
303
+ # # ]
304
+ def slice(
305
+ offset,
306
+ length = nil,
307
+ as_array: false
308
+ )
309
+ super
310
+ end
311
+
312
+ # Get the first `n` elements of the sub-arrays.
313
+ #
314
+ # @param n [Integer]
315
+ # Number of values to return for each sublist.
316
+ # @param as_array [Boolean]
317
+ # Return result as a fixed-length `Array`, otherwise as a `List`.
318
+ # If true `n` must be a constant value.
319
+ #
320
+ # @return [Series]
321
+ #
322
+ # @example
323
+ # s = Polars::Series.new(
324
+ # [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]],
325
+ # dtype: Polars::Array.new(Polars::Int64, 6)
326
+ # )
327
+ # s.arr.head
328
+ # # =>
329
+ # # shape: (2,)
330
+ # # Series: '' [list[i64]]
331
+ # # [
332
+ # # [1, 2, … 5]
333
+ # # [7, 8, … 11]
334
+ # # ]
335
+ #
336
+ # @example
337
+ # s.arr.head(3, as_array: true)
338
+ # # =>
339
+ # # shape: (2,)
340
+ # # Series: '' [array[i64, 3]]
341
+ # # [
342
+ # # [1, 2, 3]
343
+ # # [7, 8, 9]
344
+ # # ]
345
+ def head(n = 5, as_array: false)
346
+ super
347
+ end
348
+
349
+ # Slice the last `n` values of every sublist.
350
+ #
351
+ # @param n [Integer]
352
+ # Number of values to return for each sublist.
353
+ # @param as_array [Boolean]
354
+ # Return result as a fixed-length `Array`, otherwise as a `List`.
355
+ # If true `n` must be a constant value.
356
+ #
357
+ # @return [Series]
358
+ #
359
+ # @example
360
+ # s = Polars::Series.new(
361
+ # [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]],
362
+ # dtype: Polars::Array.new(Polars::Int64, 6)
363
+ # )
364
+ # s.arr.tail
365
+ # # =>
366
+ # # shape: (2,)
367
+ # # Series: '' [list[i64]]
368
+ # # [
369
+ # # [2, 3, … 6]
370
+ # # [8, 9, … 12]
371
+ # # ]
372
+ #
373
+ # @example
374
+ # s.arr.tail(3, as_array: true)
375
+ # # =>
376
+ # # shape: (2,)
377
+ # # Series: '' [array[i64, 3]]
378
+ # # [
379
+ # # [4, 5, 6]
380
+ # # [10, 11, 12]
381
+ # # ]
382
+ def tail(n = 5, as_array: false)
144
383
  super
145
384
  end
146
385
 
147
386
  # Evaluate whether all boolean values are true for every subarray.
148
387
  #
388
+ # @param ignore_nulls [Boolean]
389
+ # * If set to `true` (default), null values are ignored. If there
390
+ # are no non-null values, the output is `true`.
391
+ # * If set to `false`, [Kleene logic](https://en.wikipedia.org/wiki/Three-valued_logic) is used to deal with nulls:
392
+ # if the column contains any null values and no `false` values,
393
+ # the output is null.
394
+ #
149
395
  # @return [Series]
150
396
  #
151
397
  # @example
@@ -164,7 +410,7 @@ module Polars
164
410
  # # true
165
411
  # # null
166
412
  # # ]
167
- def all
413
+ def all(ignore_nulls: true)
168
414
  super
169
415
  end
170
416
 
@@ -263,6 +509,10 @@ module Polars
263
509
  #
264
510
  # @param index [Integer]
265
511
  # Index to return per sublist
512
+ # @param null_on_oob [Boolean]
513
+ # Behavior if an index is out of bounds:
514
+ # true -> set as null
515
+ # false -> raise an error
266
516
  #
267
517
  # @return [Series]
268
518
  #
@@ -270,7 +520,7 @@ module Polars
270
520
  # s = Polars::Series.new(
271
521
  # "a", [[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype: Polars::Array.new(Polars::Int32, 3)
272
522
  # )
273
- # s.arr.get(Polars::Series.new([1, -2, 4]))
523
+ # s.arr.get(Polars::Series.new([1, -2, 4]), null_on_oob: true)
274
524
  # # =>
275
525
  # # shape: (3,)
276
526
  # # Series: 'a' [i32]
@@ -279,7 +529,7 @@ module Polars
279
529
  # # 5
280
530
  # # null
281
531
  # # ]
282
- def get(index)
532
+ def get(index, null_on_oob: false)
283
533
  super
284
534
  end
285
535
 
@@ -334,7 +584,7 @@ module Polars
334
584
  # @param ignore_nulls [Boolean]
335
585
  # Ignore null values (default).
336
586
  #
337
- # If set to `False`, null values will be propagated.
587
+ # If set to `false`, null values will be propagated.
338
588
  # If the sub-list contains any null values, the output is `nil`.
339
589
  #
340
590
  # @return [Series]
@@ -355,6 +605,11 @@ module Polars
355
605
 
356
606
  # Returns a column with a separate row for every array element.
357
607
  #
608
+ # @param empty_as_null [Boolean]
609
+ # Explode an empty array into a `null`.
610
+ # @param keep_nulls [Boolean]
611
+ # Explode a `null` array into a `null`.
612
+ #
358
613
  # @return [Series]
359
614
  #
360
615
  # @example
@@ -371,7 +626,7 @@ module Polars
371
626
  # # 5
372
627
  # # 6
373
628
  # # ]
374
- def explode
629
+ def explode(empty_as_null: true, keep_nulls: true)
375
630
  super
376
631
  end
377
632
 
@@ -379,6 +634,8 @@ module Polars
379
634
  #
380
635
  # @param item [Object]
381
636
  # Item that will be checked for membership
637
+ # @param nulls_equal [Boolean]
638
+ # If true, treat null as a distinct value. Null values will not propagate.
382
639
  #
383
640
  # @return [Series]
384
641
  #
@@ -395,7 +652,7 @@ module Polars
395
652
  # # true
396
653
  # # false
397
654
  # # ]
398
- def contains(item)
655
+ def contains(item, nulls_equal: true)
399
656
  super
400
657
  end
401
658
 
@@ -419,5 +676,122 @@ module Polars
419
676
  def count_matches(element)
420
677
  super
421
678
  end
679
+
680
+ # Convert the series of type `Array` to a series of type `Struct`.
681
+ #
682
+ # @param fields [Object]
683
+ # If the name and number of the desired fields is known in advance
684
+ # a list of field names can be given, which will be assigned by index.
685
+ # Otherwise, to dynamically assign field names, a custom function can be
686
+ # used; if neither are set, fields will be `field_0, field_1 .. field_n`.
687
+ #
688
+ # @return [Series]
689
+ #
690
+ # @example Convert array to struct with default field name assignment:
691
+ # s1 = Polars::Series.new("n", [[0, 1, 2], [3, 4, 5]], dtype: Polars::Array.new(Polars::Int8, 3))
692
+ # s2 = s1.arr.to_struct
693
+ # s2.struct.fields
694
+ # # => ["field_0", "field_1", "field_2"]
695
+ def to_struct(fields: nil)
696
+ s = Utils.wrap_s(_s)
697
+ s.to_frame.select(F.col(s.name).arr.to_struct(fields: fields)).to_series
698
+ end
699
+
700
+ # Shift array values by the given number of indices.
701
+ #
702
+ # @param n [Integer]
703
+ # Number of indices to shift forward. If a negative value is passed, values
704
+ # are shifted in the opposite direction instead.
705
+ #
706
+ # @return [Series]
707
+ #
708
+ # @note
709
+ # This method is similar to the `LAG` operation in SQL when the value for `n`
710
+ # is positive. With a negative value for `n`, it is similar to `LEAD`.
711
+ #
712
+ # @example By default, array values are shifted forward by one index.
713
+ # s = Polars::Series.new([[1, 2, 3], [4, 5, 6]], dtype: Polars::Array.new(Polars::Int64, 3))
714
+ # s.arr.shift
715
+ # # =>
716
+ # # shape: (2,)
717
+ # # Series: '' [array[i64, 3]]
718
+ # # [
719
+ # # [null, 1, 2]
720
+ # # [null, 4, 5]
721
+ # # ]
722
+ #
723
+ # @example Pass a negative value to shift in the opposite direction instead.
724
+ # s.arr.shift(-2)
725
+ # # =>
726
+ # # shape: (2,)
727
+ # # Series: '' [array[i64, 3]]
728
+ # # [
729
+ # # [3, null, null]
730
+ # # [6, null, null]
731
+ # # ]
732
+ def shift(n = 1)
733
+ super
734
+ end
735
+
736
+ # Run any polars expression against the arrays' elements.
737
+ #
738
+ # @param expr [Expr]
739
+ # Expression to run. Note that you can select an element with `pl.element()`
740
+ # @param as_list [Boolean]
741
+ # Collect the resulting data as a list. This allows for expressions which
742
+ # output a variable amount of data.
743
+ #
744
+ # @return [Series]
745
+ #
746
+ # @example
747
+ # s = Polars::Series.new("a", [[1, 4], [8, 5], [3, 2]], dtype: Polars::Array.new(Polars::Int64, 2))
748
+ # s.arr.eval(Polars.element.rank)
749
+ # # =>
750
+ # # shape: (3,)
751
+ # # Series: 'a' [array[f64, 2]]
752
+ # # [
753
+ # # [1.0, 2.0]
754
+ # # [2.0, 1.0]
755
+ # # [2.0, 1.0]
756
+ # # ]
757
+ def eval(expr, as_list: false)
758
+ s = Utils.wrap_s(_s)
759
+ s.to_frame.select(F.col(s.name).arr.eval(expr, as_list: as_list)).to_series
760
+ end
761
+
762
+ # Run any polars aggregation expression against the arrays' elements.
763
+ #
764
+ # @param expr [Expr]
765
+ # Expression to run. Note that you can select an element with `Polars.element`.
766
+ #
767
+ # @return [Series]
768
+ #
769
+ # @example
770
+ # s = Polars::Series.new(
771
+ # "a", [[1, nil], [42, 13], [nil, nil]], dtype: Polars::Array.new(Polars::Int64, 2)
772
+ # )
773
+ # s.arr.agg(Polars.element.null_count)
774
+ # # =>
775
+ # # shape: (3,)
776
+ # # Series: 'a' [u32]
777
+ # # [
778
+ # # 1
779
+ # # 0
780
+ # # 2
781
+ # # ]
782
+ #
783
+ # @example
784
+ # s.arr.agg(Polars.element.drop_nulls)
785
+ # # =>
786
+ # # shape: (3,)
787
+ # # Series: 'a' [list[i64]]
788
+ # # [
789
+ # # [1]
790
+ # # [42, 13]
791
+ # # []
792
+ # # ]
793
+ def agg(expr)
794
+ super
795
+ end
422
796
  end
423
797
  end
@@ -1,21 +1,22 @@
1
1
  module Polars
2
2
  # @private
3
3
  class BatchedCsvReader
4
- attr_accessor :_reader, :new_columns
4
+ attr_accessor :_reader
5
5
 
6
6
  def initialize(
7
- file,
7
+ source,
8
8
  has_header: true,
9
9
  columns: nil,
10
- sep: ",",
11
- comment_char: nil,
10
+ separator: ",",
11
+ comment_prefix: nil,
12
12
  quote_char: '"',
13
13
  skip_rows: 0,
14
- dtypes: nil,
14
+ skip_lines: 0,
15
+ schema_overrides: nil,
15
16
  null_values: nil,
16
17
  missing_utf8_is_empty_string: false,
17
18
  ignore_errors: false,
18
- parse_dates: false,
19
+ try_parse_dates: false,
19
20
  n_threads: nil,
20
21
  infer_schema_length: 100,
21
22
  batch_size: 50_000,
@@ -24,79 +25,60 @@ module Polars
24
25
  low_memory: false,
25
26
  rechunk: true,
26
27
  skip_rows_after_header: 0,
27
- row_count_name: nil,
28
- row_count_offset: 0,
28
+ row_index_name: nil,
29
+ row_index_offset: 0,
29
30
  eol_char: "\n",
30
31
  new_columns: nil,
31
32
  raise_if_empty: true,
32
33
  truncate_ragged_lines: false,
33
34
  decimal_comma: false
34
35
  )
35
- if Utils.pathlike?(file)
36
- path = Utils.normalize_filepath(file)
37
- end
36
+ q = Polars.scan_csv(
37
+ source,
38
+ infer_schema_length: infer_schema_length,
39
+ has_header: has_header,
40
+ ignore_errors: ignore_errors,
41
+ n_rows: n_rows,
42
+ skip_rows: skip_rows,
43
+ skip_lines: skip_lines,
44
+ separator: separator,
45
+ rechunk: rechunk,
46
+ encoding: encoding,
47
+ schema_overrides: schema_overrides,
48
+ low_memory: low_memory,
49
+ comment_prefix: comment_prefix,
50
+ quote_char: quote_char,
51
+ null_values: null_values,
52
+ missing_utf8_is_empty_string: missing_utf8_is_empty_string,
53
+ try_parse_dates: try_parse_dates,
54
+ skip_rows_after_header: skip_rows_after_header,
55
+ row_index_name: row_index_name,
56
+ row_index_offset: row_index_offset,
57
+ eol_char: eol_char,
58
+ raise_if_empty: raise_if_empty,
59
+ truncate_ragged_lines: truncate_ragged_lines,
60
+ decimal_comma: decimal_comma,
61
+ new_columns: new_columns
62
+ )
38
63
 
39
- dtype_list = nil
40
- dtype_slice = nil
41
- if !dtypes.nil?
42
- if dtypes.is_a?(Hash)
43
- dtype_list = []
44
- dtypes.each do |k, v|
45
- dtype_list << [k, Utils.rb_type_to_dtype(v)]
46
- end
47
- elsif dtypes.is_a?(::Array)
48
- dtype_slice = dtypes
49
- else
50
- raise ArgumentError, "dtype arg should be list or dict"
51
- end
64
+ if !columns.nil?
65
+ q = q.select(columns)
52
66
  end
53
67
 
54
- processed_null_values = Utils._process_null_values(null_values)
55
- projection, columns = Utils.handle_projection_columns(columns)
56
-
57
- self._reader = RbBatchedCsv.new(
58
- infer_schema_length,
59
- batch_size,
60
- has_header,
61
- ignore_errors,
62
- n_rows,
63
- skip_rows,
64
- projection,
65
- sep,
66
- rechunk,
67
- columns,
68
- encoding,
69
- n_threads,
70
- path,
71
- dtype_list,
72
- dtype_slice,
73
- low_memory,
74
- comment_char,
75
- quote_char,
76
- processed_null_values,
77
- missing_utf8_is_empty_string,
78
- parse_dates,
79
- skip_rows_after_header,
80
- Utils.parse_row_index_args(row_count_name, row_count_offset),
81
- eol_char,
82
- raise_if_empty,
83
- truncate_ragged_lines,
84
- decimal_comma
85
- )
86
- self.new_columns = new_columns
68
+ # Trigger empty data.
69
+ if raise_if_empty
70
+ q.collect_schema
71
+ end
72
+ self._reader = q.collect_batches(chunk_size: batch_size)
87
73
  end
88
74
 
89
75
  def next_batches(n)
90
- batches = _reader.next_batches(n)
91
- if !batches.nil?
92
- if new_columns
93
- batches.map { |df| Utils._update_columns(Utils.wrap_df(df), new_columns) }
94
- else
95
- batches.map { |df| Utils.wrap_df(df) }
96
- end
97
- else
98
- nil
76
+ chunks = self._reader.take(n)
77
+
78
+ if chunks.length > 0
79
+ return chunks
99
80
  end
81
+ nil
100
82
  end
101
83
  end
102
84
  end