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
@@ -63,6 +63,13 @@ module Polars
63
63
  # in the target string.
64
64
  # @param cache [Boolean]
65
65
  # Use a cache of unique, converted datetimes to apply the conversion.
66
+ # @param ambiguous ['raise', 'earliest', 'latest', 'null']
67
+ # Determine how to deal with ambiguous datetimes:
68
+ #
69
+ # - `'raise'` (default): raise
70
+ # - `'earliest'`: use the earliest datetime
71
+ # - `'latest'`: use the latest datetime
72
+ # - `'null'`: set to null
66
73
  #
67
74
  # @return [Series]
68
75
  #
@@ -119,9 +126,9 @@ module Polars
119
126
 
120
127
  # Parse a Series of dtype Utf8 to a Date/Datetime Series.
121
128
  #
122
- # @param datatype [Symbol]
123
- # `:date`, `:dateime`, or `:time`.
124
- # @param fmt [String]
129
+ # @param dtype [Symbol]
130
+ # `:date`, `:datetime`, or `:time`.
131
+ # @param format [String]
125
132
  # Format to use, refer to the
126
133
  # [chrono strftime documentation](https://docs.rs/chrono/latest/chrono/format/strftime/index.html)
127
134
  # for specification. Example: `"%y-%m-%d"`.
@@ -132,6 +139,13 @@ module Polars
132
139
  # - If false, allow the format to match anywhere in the target string.
133
140
  # @param cache [Boolean]
134
141
  # Use a cache of unique, converted dates to apply the datetime conversion.
142
+ # @param ambiguous ['raise', 'earliest', 'latest', 'null']
143
+ # Determine how to deal with ambiguous datetimes:
144
+ #
145
+ # - `'raise'` (default): raise
146
+ # - `'earliest'`: use the earliest datetime
147
+ # - `'latest'`: use the latest datetime
148
+ # - `'null'`: set to null
135
149
  #
136
150
  # @return [Series]
137
151
  #
@@ -173,86 +187,83 @@ module Polars
173
187
  # # 2022-01-31
174
188
  # # 2001-07-08
175
189
  # # ]
176
- def strptime(datatype, fmt = nil, strict: true, exact: true, cache: true)
190
+ def strptime(dtype, format = nil, strict: true, exact: true, cache: true, ambiguous: "raise")
177
191
  super
178
192
  end
179
193
 
180
- # Get length of the string values in the Series (as number of bytes).
194
+ # Convert a String column into a Decimal column.
181
195
  #
182
- # @return [Series]
196
+ # This method infers the needed parameters `precision` and `scale`.
183
197
  #
184
- # @note
185
- # The returned lengths are equal to the number of bytes in the UTF8 string. If you
186
- # need the length in terms of the number of characters, use `n_chars` instead.
198
+ # @param inference_length [Integer]
199
+ # Number of elements to parse to determine the `precision` and `scale`
200
+ #
201
+ # @return [Series]
187
202
  #
188
203
  # @example
189
- # s = Polars::Series.new(["Café", nil, "345", "東京"])
190
- # s.str.lengths
204
+ # s = Polars::Series.new(
205
+ # ["40.12", "3420.13", "120134.19", "3212.98", "12.90", "143.09", "143.9"]
206
+ # )
207
+ # s.str.to_decimal
191
208
  # # =>
192
- # # shape: (4,)
193
- # # Series: '' [u32]
209
+ # # shape: (7,)
210
+ # # Series: '' [decimal[8,2]]
194
211
  # # [
195
- # # 5
196
- # # null
197
- # # 3
198
- # # 6
212
+ # # 40.12
213
+ # # 3420.13
214
+ # # 120134.19
215
+ # # 3212.98
216
+ # # 12.90
217
+ # # 143.09
218
+ # # 143.90
199
219
  # # ]
200
- def lengths
201
- super
220
+ def to_decimal(inference_length = 100, scale: nil)
221
+ if !scale.nil?
222
+ raise Todo
223
+ end
224
+
225
+ Utils.wrap_s(_s.str_to_decimal_infer(inference_length))
202
226
  end
203
227
 
204
- # Get length of the string values in the Series (as number of chars).
228
+ # Return the length of each string as the number of bytes.
205
229
  #
206
230
  # @return [Series]
207
231
  #
208
- # @note
209
- # If you know that you are working with ASCII text, `lengths` will be
210
- # equivalent, and faster (returns length in terms of the number of bytes).
211
- #
212
232
  # @example
213
- # s = Polars::Series.new(["Café", nil, "345", "東京"])
214
- # s.str.n_chars
233
+ # s = Polars::Series.new(["Café", "345", "東京", nil])
234
+ # s.str.len_bytes
215
235
  # # =>
216
236
  # # shape: (4,)
217
237
  # # Series: '' [u32]
218
238
  # # [
219
- # # 4
220
- # # null
239
+ # # 5
221
240
  # # 3
222
- # # 2
241
+ # # 6
242
+ # # null
223
243
  # # ]
224
- def n_chars
244
+ def len_bytes
225
245
  super
226
246
  end
227
247
 
228
- # Vertically concat the values in the Series to a single string value.
229
- #
230
- # @param delimiter [String]
231
- # The delimiter to insert between consecutive string values.
248
+ # Return the length of each string as the number of characters.
232
249
  #
233
250
  # @return [Series]
234
251
  #
235
252
  # @example
236
- # Polars::Series.new([1, nil, 2]).str.join("-")
237
- # # =>
238
- # # shape: (1,)
239
- # # Series: '' [str]
240
- # # [
241
- # # "1-2"
242
- # # ]
243
- #
244
- # @example
245
- # Polars::Series.new([1, nil, 2]).str.join("-", ignore_nulls: false)
253
+ # s = Polars::Series.new(["Café", "345", "東京", nil])
254
+ # s.str.len_chars
246
255
  # # =>
247
- # # shape: (1,)
248
- # # Series: '' [str]
256
+ # # shape: (4,)
257
+ # # Series: '' [u32]
249
258
  # # [
259
+ # # 4
260
+ # # 3
261
+ # # 2
250
262
  # # null
251
263
  # # ]
252
- def join(delimiter = "-", ignore_nulls: true)
264
+ def len_chars
253
265
  super
254
266
  end
255
- alias_method :concat, :join
256
267
 
257
268
  # Check if strings in Series contain a substring that matches a regex.
258
269
  #
@@ -260,6 +271,9 @@ module Polars
260
271
  # A valid regex pattern.
261
272
  # @param literal [Boolean]
262
273
  # Treat pattern as a literal string.
274
+ # @param strict [Boolean]
275
+ # Raise an error if the underlying pattern is not a valid regex,
276
+ # otherwise mask out with a null value.
263
277
  #
264
278
  # @return [Series]
265
279
  #
@@ -287,13 +301,72 @@ module Polars
287
301
  # # true
288
302
  # # null
289
303
  # # ]
290
- def contains(pattern, literal: false)
304
+ def contains(pattern, literal: false, strict: true)
305
+ super
306
+ end
307
+
308
+ # Return the bytes offset of the first substring matching a pattern.
309
+ #
310
+ # If the pattern is not found, returns nil.
311
+ #
312
+ # @param pattern
313
+ # A valid regular expression pattern, compatible with the [regex crate](https://docs.rs/regex/latest/regex/).
314
+ # @param literal
315
+ # Treat `pattern` as a literal string, not as a regular expression.
316
+ # @param strict
317
+ # Raise an error if the underlying pattern is not a valid regex,
318
+ # otherwise mask out with a null value.
319
+ #
320
+ # @return [Series]
321
+ #
322
+ # @note
323
+ # To modify regular expression behaviour (such as case-sensitivity) with
324
+ # flags, use the inline `(?iLmsuxU)` syntax.
325
+ #
326
+ # @example Find the index of the first substring matching a regex pattern:
327
+ # s = Polars::Series.new("txt", ["Crab", "Lobster", nil, "Crustacean"])
328
+ # s.str.find("a|e").rename("idx_rx")
329
+ # # =>
330
+ # # shape: (4,)
331
+ # # Series: 'idx_rx' [u32]
332
+ # # [
333
+ # # 2
334
+ # # 5
335
+ # # null
336
+ # # 5
337
+ # # ]
338
+ #
339
+ # @example Find the index of the first substring matching a literal pattern:
340
+ # s.str.find("e", literal: true).rename("idx_lit")
341
+ # # =>
342
+ # # shape: (4,)
343
+ # # Series: 'idx_lit' [u32]
344
+ # # [
345
+ # # null
346
+ # # 5
347
+ # # null
348
+ # # 7
349
+ # # ]
350
+ #
351
+ # @example Match against a pattern found in another column or (expression):
352
+ # p = Polars::Series.new("pat", ["a[bc]", "b.t", "[aeiuo]", "(?i)A[BC]"])
353
+ # s.str.find(p).rename("idx")
354
+ # # =>
355
+ # # shape: (4,)
356
+ # # Series: 'idx' [u32]
357
+ # # [
358
+ # # 2
359
+ # # 2
360
+ # # null
361
+ # # 5
362
+ # # ]
363
+ def find(pattern, literal: false, strict: true)
291
364
  super
292
365
  end
293
366
 
294
367
  # Check if string values end with a substring.
295
368
  #
296
- # @param sub [String]
369
+ # @param suffix [String]
297
370
  # Suffix substring.
298
371
  #
299
372
  # @return [Series]
@@ -309,13 +382,13 @@ module Polars
309
382
  # # true
310
383
  # # null
311
384
  # # ]
312
- def ends_with(sub)
385
+ def ends_with(suffix)
313
386
  super
314
387
  end
315
388
 
316
389
  # Check if string values start with a substring.
317
390
  #
318
- # @param sub [String]
391
+ # @param prefix [String]
319
392
  # Prefix substring.
320
393
  #
321
394
  # @return [Series]
@@ -331,7 +404,7 @@ module Polars
331
404
  # # false
332
405
  # # null
333
406
  # # ]
334
- def starts_with(sub)
407
+ def starts_with(prefix)
335
408
  super
336
409
  end
337
410
 
@@ -358,7 +431,7 @@ module Polars
358
431
  # # b"bar"
359
432
  # # null
360
433
  # # ]
361
- def decode(encoding, strict: false)
434
+ def decode(encoding, strict: true)
362
435
  super
363
436
  end
364
437
 
@@ -384,6 +457,43 @@ module Polars
384
457
  super
385
458
  end
386
459
 
460
+ # Parse string values as JSON.
461
+ #
462
+ # Throws an error if invalid JSON strings are encountered.
463
+ #
464
+ # @param dtype [Object]
465
+ # The dtype to cast the extracted value to. If nil, the dtype will be
466
+ # inferred from the JSON value.
467
+ # @param infer_schema_length [Integer]
468
+ # The maximum number of rows to scan for schema inference.
469
+ # If set to `nil`, the full data may be scanned *(this is slow)*.
470
+ #
471
+ # @return [Series]
472
+ #
473
+ # @example
474
+ # s = Polars::Series.new("json", ['{"a":1, "b": true}', nil, '{"a":2, "b": false}'])
475
+ # s.str.json_decode
476
+ # # =>
477
+ # # shape: (3,)
478
+ # # Series: 'json' [struct[2]]
479
+ # # [
480
+ # # {1,true}
481
+ # # null
482
+ # # {2,false}
483
+ # # ]
484
+ def json_decode(dtype = nil, infer_schema_length: N_INFER_DEFAULT)
485
+ if !dtype.nil?
486
+ s = Utils.wrap_s(_s)
487
+ return (
488
+ s.to_frame
489
+ .select_seq(F.col(s.name).str.json_decode(dtype))
490
+ .to_series
491
+ )
492
+ end
493
+
494
+ Utils.wrap_s(_s.str_json_decode(infer_schema_length))
495
+ end
496
+
387
497
  # Extract the first match of json string with provided JSONPath expression.
388
498
  #
389
499
  # Throw errors if encounter invalid json strings.
@@ -468,16 +578,51 @@ module Polars
468
578
  super
469
579
  end
470
580
 
581
+ # Extract all capture groups for the given regex pattern.
582
+ #
583
+ # @param pattern [String]
584
+ # A valid regular expression pattern containing at least one capture group,
585
+ # compatible with the [regex crate](https://docs.rs/regex/latest/regex/).
586
+ #
587
+ # @return [Series]
588
+ #
589
+ # @note
590
+ # All group names are **strings**.
591
+ #
592
+ # @example
593
+ # s = Polars::Series.new(
594
+ # "url",
595
+ # [
596
+ # "http://vote.com/ballon_dor?candidate=messi&ref=python",
597
+ # "http://vote.com/ballon_dor?candidate=weghorst&ref=polars",
598
+ # "http://vote.com/ballon_dor?error=404&ref=rust"
599
+ # ]
600
+ # )
601
+ # s.str.extract_groups("candidate=(?<candidate>\\w+)&ref=(?<ref>\\w+)")
602
+ # # =>
603
+ # # shape: (3,)
604
+ # # Series: 'url' [struct[2]]
605
+ # # [
606
+ # # {"messi","python"}
607
+ # # {"weghorst","polars"}
608
+ # # {null,null}
609
+ # # ]
610
+ def extract_groups(pattern)
611
+ super
612
+ end
613
+
471
614
  # Count all successive non-overlapping regex matches.
472
615
  #
473
616
  # @param pattern [String]
474
617
  # A valid regex pattern
618
+ # @param literal [Boolean]
619
+ # Treat `pattern` as a literal string, not as a regular expression.
475
620
  #
476
621
  # @return [Series]
477
622
  #
478
623
  # @example
479
624
  # s = Polars::Series.new("foo", ["123 bla 45 asd", "xyz 678 910t"])
480
- # s.str.count_match('\d')
625
+ # s.str.count_matches('\d')
481
626
  # # =>
482
627
  # # shape: (2,)
483
628
  # # Series: 'foo' [u32]
@@ -485,7 +630,7 @@ module Polars
485
630
  # # 5
486
631
  # # 6
487
632
  # # ]
488
- def count_match(pattern)
633
+ def count_matches(pattern, literal: false)
489
634
  super
490
635
  end
491
636
 
@@ -610,6 +755,8 @@ module Polars
610
755
  # Substring to replace.
611
756
  # @param literal [Boolean]
612
757
  # Treat pattern as a literal string.
758
+ # @param n [Integer]
759
+ # Number of matches to replace.
613
760
  #
614
761
  # @return [Series]
615
762
  #
@@ -623,7 +770,7 @@ module Polars
623
770
  # # "123ABC"
624
771
  # # "abc456"
625
772
  # # ]
626
- def replace(pattern, value, literal: false)
773
+ def replace(pattern, value, literal: false, n: 1)
627
774
  super
628
775
  end
629
776
 
@@ -654,8 +801,10 @@ module Polars
654
801
 
655
802
  # Remove leading and trailing whitespace.
656
803
  #
657
- # @param matches [String, nil]
658
- # An optional single character that should be trimmed
804
+ # @param characters [String]
805
+ # The set of characters to be removed. All combinations of this set of
806
+ # characters will be stripped from the start and end of the string. If set to
807
+ # nil (default), all leading and trailing whitespace is removed instead.
659
808
  #
660
809
  # @return [Series]
661
810
  #
@@ -669,14 +818,16 @@ module Polars
669
818
  # # "hello"
670
819
  # # "world"
671
820
  # # ]
672
- def strip_chars(matches = nil)
821
+ def strip_chars(characters = nil)
673
822
  super
674
823
  end
675
824
 
676
825
  # Remove leading whitespace.
677
826
  #
678
- # @param matches [String, nil]
679
- # An optional single character that should be trimmed
827
+ # @param characters [String]
828
+ # The set of characters to be removed. All combinations of this set of
829
+ # characters will be stripped from the start of the string. If set to
830
+ # nil (default), all leading and trailing whitespace is removed instead.
680
831
  #
681
832
  # @return [Series]
682
833
  #
@@ -690,15 +841,16 @@ module Polars
690
841
  # # "hello "
691
842
  # # "world"
692
843
  # # ]
693
- def strip_chars_start(matches = nil)
844
+ def strip_chars_start(characters = nil)
694
845
  super
695
846
  end
696
- alias_method :lstrip, :strip_chars_start
697
847
 
698
848
  # Remove trailing whitespace.
699
849
  #
700
- # @param matches [String, nil]
701
- # An optional single character that should be trimmed
850
+ # @param characters [String]
851
+ # The set of characters to be removed. All combinations of this set of
852
+ # characters will be stripped from the end of the string. If set to
853
+ # nil (default), all leading and trailing whitespace is removed instead.
702
854
  #
703
855
  # @return [Series]
704
856
  #
@@ -712,94 +864,139 @@ module Polars
712
864
  # # " hello"
713
865
  # # "world"
714
866
  # # ]
715
- def strip_chars_end(matches = nil)
867
+ def strip_chars_end(characters = nil)
716
868
  super
717
869
  end
718
- alias_method :rstrip, :strip_chars_end
719
870
 
720
- # Fills the string with zeroes.
871
+ # Remove prefix.
721
872
  #
722
- # Return a copy of the string left filled with ASCII '0' digits to make a string
723
- # of length width.
873
+ # The prefix will be removed from the string exactly once, if found.
724
874
  #
725
- # A leading sign prefix ('+'/'-') is handled by inserting the padding after the
726
- # sign character rather than before. The original string is returned if width is
727
- # less than or equal to `s.length`.
728
- #
729
- # @param length [Integer]
730
- # Fill the value up to this length.
875
+ # @param prefix [String]
876
+ # The prefix to be removed.
731
877
  #
732
878
  # @return [Series]
733
879
  #
734
880
  # @example
735
- # s = Polars::Series.new([-1, 123, 999999, nil])
736
- # s.cast(Polars::String).str.zfill(4)
881
+ # s = Polars::Series.new(["foobar", "foofoobar", "foo", "bar"])
882
+ # s.str.strip_prefix("foo")
737
883
  # # =>
738
884
  # # shape: (4,)
739
885
  # # Series: '' [str]
740
886
  # # [
741
- # # "-001"
742
- # # "0123"
743
- # # "999999"
744
- # # null
887
+ # # "bar"
888
+ # # "foobar"
889
+ # # ""
890
+ # # "bar"
745
891
  # # ]
746
- def zfill(length)
892
+ def strip_prefix(prefix)
747
893
  super
748
894
  end
749
895
 
750
- # Return the string left justified in a string of length `width`.
896
+ # Remove suffix.
897
+ #
898
+ # The suffix will be removed from the string exactly once, if found.
899
+ #
900
+ # @param suffix [String]
901
+ # The suffix to be removed.
751
902
  #
752
- # Padding is done using the specified `fillchar`. The original string is
753
- # returned if `width` is less than or equal to `s.length`.
903
+ # @return [Series]
904
+ #
905
+ # @example
906
+ # s = Polars::Series.new(["foobar", "foobarbar", "foo", "bar"])
907
+ # s.str.strip_suffix("bar")
908
+ # # =>
909
+ # # shape: (4,)
910
+ # # Series: '' [str]
911
+ # # [
912
+ # # "foo"
913
+ # # "foobar"
914
+ # # "foo"
915
+ # # ""
916
+ # # ]
917
+ def strip_suffix(suffix)
918
+ super
919
+ end
920
+
921
+ # Pad the start of the string until it reaches the given length.
754
922
  #
755
- # @param width [Integer]
756
- # Justify left to this length.
757
- # @param fillchar [String]
758
- # Fill with this ASCII character.
923
+ # @param length [Integer]
924
+ # Pad the string until it reaches this length. Strings with length equal to or
925
+ # greater than this value are returned as-is.
926
+ # @param fill_char [String]
927
+ # The character to pad the string with.
759
928
  #
760
929
  # @return [Series]
761
930
  #
762
931
  # @example
763
- # s = Polars::Series.new("a", ["cow", "monkey", nil, "hippopotamus"])
764
- # s.str.ljust(8, "*")
932
+ # s = Polars::Series.new("a", ["cow", "monkey", "hippopotamus", nil])
933
+ # s.str.pad_start(8, "*")
765
934
  # # =>
766
935
  # # shape: (4,)
767
936
  # # Series: 'a' [str]
768
937
  # # [
938
+ # # "*****cow"
939
+ # # "**monkey"
940
+ # # "hippopotamus"
941
+ # # null
942
+ # # ]
943
+ def pad_start(length, fill_char = " ")
944
+ super
945
+ end
946
+
947
+ # Pad the end of the string until it reaches the given length.
948
+ #
949
+ # @param length [Integer]
950
+ # Pad the string until it reaches this length. Strings with length equal to or
951
+ # greater than this value are returned as-is.
952
+ # @param fill_char [String]
953
+ # The character to pad the string with.
954
+ #
955
+ # @return [Series]
956
+ #
957
+ # @example
958
+ # s = Polars::Series.new(["cow", "monkey", "hippopotamus", nil])
959
+ # s.str.pad_end(8, "*")
960
+ # # =>
961
+ # # shape: (4,)
962
+ # # Series: '' [str]
963
+ # # [
769
964
  # # "cow*****"
770
965
  # # "monkey**"
771
- # # null
772
966
  # # "hippopotamus"
967
+ # # null
773
968
  # # ]
774
- def ljust(width, fillchar = " ")
969
+ def pad_end(length, fill_char = " ")
775
970
  super
776
971
  end
777
972
 
778
- # Return the string right justified in a string of length `width`.
973
+ # Fills the string with zeroes.
779
974
  #
780
- # Padding is done using the specified `fillchar`. The original string is
781
- # returned if `width` is less than or equal to `s.length`.
975
+ # Return a copy of the string left filled with ASCII '0' digits to make a string
976
+ # of length width.
782
977
  #
783
- # @param width [Integer]
784
- # Justify right to this length.
785
- # @param fillchar [String]
786
- # Fill with this ASCII character.
978
+ # A leading sign prefix ('+'/'-') is handled by inserting the padding after the
979
+ # sign character rather than before. The original string is returned if width is
980
+ # less than or equal to `s.length`.
981
+ #
982
+ # @param length [Integer]
983
+ # Fill the value up to this length.
787
984
  #
788
985
  # @return [Series]
789
986
  #
790
987
  # @example
791
- # s = Polars::Series.new("a", ["cow", "monkey", nil, "hippopotamus"])
792
- # s.str.rjust(8, "*")
988
+ # s = Polars::Series.new([-1, 123, 999999, nil])
989
+ # s.cast(Polars::String).str.zfill(4)
793
990
  # # =>
794
991
  # # shape: (4,)
795
- # # Series: 'a' [str]
992
+ # # Series: '' [str]
796
993
  # # [
797
- # # "*****cow"
798
- # # "**monkey"
994
+ # # "-001"
995
+ # # "0123"
996
+ # # "999999"
799
997
  # # null
800
- # # "hippopotamus"
801
998
  # # ]
802
- def rjust(width, fillchar = " ")
999
+ def zfill(length)
803
1000
  super
804
1001
  end
805
1002
 
@@ -839,6 +1036,25 @@ module Polars
839
1036
  super
840
1037
  end
841
1038
 
1039
+ # Returns string values in reversed order.
1040
+ #
1041
+ # @return [Series]
1042
+ #
1043
+ # @example
1044
+ # s = Polars::Series.new("text", ["foo", "bar", "man\u0303ana"])
1045
+ # s.str.reverse
1046
+ # # =>
1047
+ # # shape: (3,)
1048
+ # # Series: 'text' [str]
1049
+ # # [
1050
+ # # "oof"
1051
+ # # "rab"
1052
+ # # "anañam"
1053
+ # # ]
1054
+ def reverse
1055
+ super
1056
+ end
1057
+
842
1058
  # Create subslices of the string values of a Utf8 Series.
843
1059
  #
844
1060
  # @param offset [Integer]
@@ -877,5 +1093,461 @@ module Polars
877
1093
  s = Utils.wrap_s(_s)
878
1094
  s.to_frame.select(Polars.col(s.name).str.slice(offset, length)).to_series
879
1095
  end
1096
+
1097
+ # Return the first n characters of each string in a String Series.
1098
+ #
1099
+ # @param n [Object]
1100
+ # Length of the slice (integer or expression). Negative indexing is supported;
1101
+ # see note (2) below.
1102
+ #
1103
+ # @return [Series]
1104
+ #
1105
+ # @example Return up to the first 5 characters.
1106
+ # s = Polars::Series.new(["pear", nil, "papaya", "dragonfruit"])
1107
+ # s.str.head(5)
1108
+ # # =>
1109
+ # # shape: (4,)
1110
+ # # Series: '' [str]
1111
+ # # [
1112
+ # # "pear"
1113
+ # # null
1114
+ # # "papay"
1115
+ # # "drago"
1116
+ # # ]
1117
+ #
1118
+ # @example Return up to the 3rd character from the end.
1119
+ # s = Polars::Series.new(["pear", nil, "papaya", "dragonfruit"])
1120
+ # s.str.head(-3)
1121
+ # # =>
1122
+ # # shape: (4,)
1123
+ # # Series: '' [str]
1124
+ # # [
1125
+ # # "p"
1126
+ # # null
1127
+ # # "pap"
1128
+ # # "dragonfr"
1129
+ # # ]
1130
+ def head(n)
1131
+ super
1132
+ end
1133
+
1134
+ # Return the last n characters of each string in a String Series.
1135
+ #
1136
+ # @param n [Object]
1137
+ # Length of the slice (integer or expression). Negative indexing is supported;
1138
+ # see note (2) below.
1139
+ #
1140
+ # @return [Series]
1141
+ #
1142
+ # @example Return up to the last 5 characters:
1143
+ # s = Polars::Series.new(["pear", nil, "papaya", "dragonfruit"])
1144
+ # s.str.tail(5)
1145
+ # # =>
1146
+ # # shape: (4,)
1147
+ # # Series: '' [str]
1148
+ # # [
1149
+ # # "pear"
1150
+ # # null
1151
+ # # "apaya"
1152
+ # # "fruit"
1153
+ # # ]
1154
+ #
1155
+ # @example Return from the 3rd character to the end:
1156
+ # s = Polars::Series.new(["pear", nil, "papaya", "dragonfruit"])
1157
+ # s.str.tail(-3)
1158
+ # # =>
1159
+ # # shape: (4,)
1160
+ # # Series: '' [str]
1161
+ # # [
1162
+ # # "r"
1163
+ # # null
1164
+ # # "aya"
1165
+ # # "gonfruit"
1166
+ # # ]
1167
+ def tail(n)
1168
+ super
1169
+ end
1170
+
1171
+ # Convert an String column into a column of dtype with base radix.
1172
+ #
1173
+ # @param base [Integer]
1174
+ # Positive integer or expression which is the base of the string
1175
+ # we are parsing.
1176
+ # Default: 10.
1177
+ # @param dtype [Object]
1178
+ # Polars integer type to cast to.
1179
+ # Default: `Int64`.
1180
+ # @param strict [Object]
1181
+ # Bool, Default=true will raise any ParseError or overflow as ComputeError.
1182
+ # false silently convert to Null.
1183
+ #
1184
+ # @return [Series]
1185
+ #
1186
+ # @example
1187
+ # s = Polars::Series.new("bin", ["110", "101", "010", "invalid"])
1188
+ # s.str.to_integer(base: 2, dtype: Polars::Int32, strict: false)
1189
+ # # =>
1190
+ # # shape: (4,)
1191
+ # # Series: 'bin' [i32]
1192
+ # # [
1193
+ # # 6
1194
+ # # 5
1195
+ # # 2
1196
+ # # null
1197
+ # # ]
1198
+ #
1199
+ # @example
1200
+ # s = Polars::Series.new("hex", ["fa1e", "ff00", "cafe", nil])
1201
+ # s.str.to_integer(base: 16)
1202
+ # # =>
1203
+ # # shape: (4,)
1204
+ # # Series: 'hex' [i64]
1205
+ # # [
1206
+ # # 64030
1207
+ # # 65280
1208
+ # # 51966
1209
+ # # null
1210
+ # # ]
1211
+ def to_integer(
1212
+ base: 10,
1213
+ dtype: Int64,
1214
+ strict: true
1215
+ )
1216
+ super
1217
+ end
1218
+
1219
+ # Use the Aho-Corasick algorithm to find matches.
1220
+ #
1221
+ # Determines if any of the patterns are contained in the string.
1222
+ #
1223
+ # @param patterns [Object]
1224
+ # String patterns to search.
1225
+ # @param ascii_case_insensitive [Boolean]
1226
+ # Enable ASCII-aware case-insensitive matching.
1227
+ # When this option is enabled, searching will be performed without respect
1228
+ # to case for ASCII letters (a-z and A-Z) only.
1229
+ #
1230
+ # @return [Series]
1231
+ #
1232
+ # @note
1233
+ # This method supports matching on string literals only, and does not support
1234
+ # regular expression matching.
1235
+ #
1236
+ # @example
1237
+ # s = Polars::Series.new(
1238
+ # "lyrics",
1239
+ # [
1240
+ # "Everybody wants to rule the world",
1241
+ # "Tell me what you want, what you really really want",
1242
+ # "Can you feel the love tonight"
1243
+ # ]
1244
+ # )
1245
+ # s.str.contains_any(["you", "me"])
1246
+ # # =>
1247
+ # # shape: (3,)
1248
+ # # Series: 'lyrics' [bool]
1249
+ # # [
1250
+ # # false
1251
+ # # true
1252
+ # # true
1253
+ # # ]
1254
+ def contains_any(
1255
+ patterns,
1256
+ ascii_case_insensitive: false
1257
+ )
1258
+ super
1259
+ end
1260
+
1261
+ # Use the Aho-Corasick algorithm to replace many matches.
1262
+ #
1263
+ # @param patterns [Object]
1264
+ # String patterns to search and replace.
1265
+ # Also accepts a mapping of patterns to their replacement as syntactic sugar
1266
+ # for `replace_many(Polars::Series.new(mapping.keys), Polars::Series.new(mapping.values))`.
1267
+ # @param replace_with [Object]
1268
+ # Strings to replace where a pattern was a match.
1269
+ # Length must match the length of `patterns` or have length 1. This can be
1270
+ # broadcasted, so it supports many:one and many:many.
1271
+ # @param ascii_case_insensitive [Boolean]
1272
+ # Enable ASCII-aware case-insensitive matching.
1273
+ # When this option is enabled, searching will be performed without respect
1274
+ # to case for ASCII letters (a-z and A-Z) only.
1275
+ # @param leftmost [Boolean]
1276
+ # Guarantees in case there are overlapping matches that the leftmost match
1277
+ # is used. In case there are multiple candidates for the leftmost match
1278
+ # the pattern which comes first in patterns is used.
1279
+ #
1280
+ # @return [Series]
1281
+ #
1282
+ # @note
1283
+ # This method supports matching on string literals only, and does not support
1284
+ # regular expression matching.
1285
+ #
1286
+ # @example Replace many patterns by passing lists of equal length to the `patterns` and `replace_with` parameters.
1287
+ # s = Polars::Series.new(
1288
+ # "lyrics",
1289
+ # [
1290
+ # "Everybody wants to rule the world",
1291
+ # "Tell me what you want, what you really really want",
1292
+ # "Can you feel the love tonight"
1293
+ # ]
1294
+ # )
1295
+ # s.str.replace_many(["you", "me"], ["me", "you"])
1296
+ # # =>
1297
+ # # shape: (3,)
1298
+ # # Series: 'lyrics' [str]
1299
+ # # [
1300
+ # # "Everybody wants to rule the wo…
1301
+ # # "Tell you what me want, what me…
1302
+ # # "Can me feel the love tonight"
1303
+ # # ]
1304
+ #
1305
+ # @example Broadcast a replacement for many patterns by passing an array of length 1 to the `replace_with` parameter.
1306
+ # s = Polars::Series.new(
1307
+ # "lyrics",
1308
+ # [
1309
+ # "Everybody wants to rule the world",
1310
+ # "Tell me what you want, what you really really want",
1311
+ # "Can you feel the love tonight",
1312
+ # ]
1313
+ # )
1314
+ # s.str.replace_many(["me", "you", "they"], [""])
1315
+ # # =>
1316
+ # # shape: (3,)
1317
+ # # Series: 'lyrics' [str]
1318
+ # # [
1319
+ # # "Everybody wants to rule the wo…
1320
+ # # "Tell what want, what really…
1321
+ # # "Can feel the love tonight"
1322
+ # # ]
1323
+ #
1324
+ # @example Passing a mapping with patterns and replacements is also supported as syntactic sugar.
1325
+ # s = Polars::Series.new(
1326
+ # "lyrics",
1327
+ # [
1328
+ # "Everybody wants to rule the world",
1329
+ # "Tell me what you want, what you really really want",
1330
+ # "Can you feel the love tonight"
1331
+ # ]
1332
+ # )
1333
+ # mapping = {"me" => "you", "you" => "me", "want" => "need"}
1334
+ # s.str.replace_many(mapping)
1335
+ # # =>
1336
+ # # shape: (3,)
1337
+ # # Series: 'lyrics' [str]
1338
+ # # [
1339
+ # # "Everybody needs to rule the wo…
1340
+ # # "Tell you what me need, what me…
1341
+ # # "Can me feel the love tonight"
1342
+ # # ]
1343
+ def replace_many(
1344
+ patterns,
1345
+ replace_with = NO_DEFAULT,
1346
+ ascii_case_insensitive: false,
1347
+ leftmost: false
1348
+ )
1349
+ super
1350
+ end
1351
+
1352
+ # Use the Aho-Corasick algorithm to extract many matches.
1353
+ #
1354
+ # @param patterns [Object]
1355
+ # String patterns to search.
1356
+ # @param ascii_case_insensitive [Boolean]
1357
+ # Enable ASCII-aware case-insensitive matching.
1358
+ # When this option is enabled, searching will be performed without respect
1359
+ # to case for ASCII letters (a-z and A-Z) only.
1360
+ # @param overlapping [Boolean]
1361
+ # Whether matches may overlap.
1362
+ # @param leftmost [Boolean]
1363
+ # Guarantees in case there are overlapping matches that the leftmost match
1364
+ # is used. In case there are multiple candidates for the leftmost match
1365
+ # the pattern which comes first in patterns is used. May not be used
1366
+ # together with overlapping: true.
1367
+ #
1368
+ # @return [Series]
1369
+ #
1370
+ # @note
1371
+ # This method supports matching on string literals only, and does not support
1372
+ # regular expression matching.
1373
+ #
1374
+ # @example
1375
+ # s = Polars::Series.new("values", ["discontent"])
1376
+ # patterns = ["winter", "disco", "onte", "discontent"]
1377
+ # s.str.extract_many(patterns, overlapping: true)
1378
+ # # =>
1379
+ # # shape: (1,)
1380
+ # # Series: 'values' [list[str]]
1381
+ # # [
1382
+ # # ["disco", "onte", "discontent"]
1383
+ # # ]
1384
+ def extract_many(
1385
+ patterns,
1386
+ ascii_case_insensitive: false,
1387
+ overlapping: false,
1388
+ leftmost: false
1389
+ )
1390
+ super
1391
+ end
1392
+
1393
+ # Use the Aho-Corasick algorithm to find all matches.
1394
+ #
1395
+ # The function returns the byte offset of the start of each match.
1396
+ # The return type will be `List<UInt32>`
1397
+ #
1398
+ # @param patterns [Object]
1399
+ # String patterns to search.
1400
+ # @param ascii_case_insensitive [Boolean]
1401
+ # Enable ASCII-aware case-insensitive matching.
1402
+ # When this option is enabled, searching will be performed without respect
1403
+ # to case for ASCII letters (a-z and A-Z) only.
1404
+ # @param overlapping [Boolean]
1405
+ # Whether matches may overlap.
1406
+ # @param leftmost [Boolean]
1407
+ # Guarantees in case there are overlapping matches that the leftmost match
1408
+ # is used. In case there are multiple candidates for the leftmost match
1409
+ # the pattern which comes first in patterns is used. May not be used
1410
+ # together with overlapping: true.
1411
+ #
1412
+ # @return [Series]
1413
+ #
1414
+ # @note
1415
+ # This method supports matching on string literals only, and does not support
1416
+ # regular expression matching.
1417
+ #
1418
+ # @example
1419
+ # df = Polars::DataFrame.new({"values" => ["discontent"]})
1420
+ # patterns = ["winter", "disco", "onte", "discontent"]
1421
+ # df.with_columns(
1422
+ # Polars.col("values")
1423
+ # .str.extract_many(patterns, overlapping: false)
1424
+ # .alias("matches"),
1425
+ # Polars.col("values")
1426
+ # .str.extract_many(patterns, overlapping: true)
1427
+ # .alias("matches_overlapping")
1428
+ # )
1429
+ # # =>
1430
+ # # shape: (1, 3)
1431
+ # # ┌────────────┬───────────┬─────────────────────────────────┐
1432
+ # # │ values ┆ matches ┆ matches_overlapping │
1433
+ # # │ --- ┆ --- ┆ --- │
1434
+ # # │ str ┆ list[str] ┆ list[str] │
1435
+ # # ╞════════════╪═══════════╪═════════════════════════════════╡
1436
+ # # │ discontent ┆ ["disco"] ┆ ["disco", "onte", "discontent"… │
1437
+ # # └────────────┴───────────┴─────────────────────────────────┘
1438
+ #
1439
+ # @example
1440
+ # df = Polars::DataFrame.new(
1441
+ # {
1442
+ # "values" => ["discontent", "rhapsody"],
1443
+ # "patterns" => [
1444
+ # ["winter", "disco", "onte", "discontent"],
1445
+ # ["rhap", "ody", "coalesce"]
1446
+ # ]
1447
+ # }
1448
+ # )
1449
+ # df.select(Polars.col("values").str.find_many("patterns"))
1450
+ # # =>
1451
+ # # shape: (2, 1)
1452
+ # # ┌───────────┐
1453
+ # # │ values │
1454
+ # # │ --- │
1455
+ # # │ list[u32] │
1456
+ # # ╞═══════════╡
1457
+ # # │ [0] │
1458
+ # # │ [0, 5] │
1459
+ # # └───────────┘
1460
+ def find_many(
1461
+ patterns,
1462
+ ascii_case_insensitive: false,
1463
+ overlapping: false,
1464
+ leftmost: false
1465
+ )
1466
+ super
1467
+ end
1468
+
1469
+ # Vertically concat the values in the Series to a single string value.
1470
+ #
1471
+ # @param delimiter [String]
1472
+ # The delimiter to insert between consecutive string values.
1473
+ # @param ignore_nulls [Boolean]
1474
+ # Ignore null values (default).
1475
+ # If set to `false`, null values will be propagated. This means that
1476
+ # if the column contains any null values, the output is null.
1477
+ #
1478
+ # @return [Series]
1479
+ #
1480
+ # @example
1481
+ # Polars::Series.new([1, nil, 2]).str.join("-")
1482
+ # # =>
1483
+ # # shape: (1,)
1484
+ # # Series: '' [str]
1485
+ # # [
1486
+ # # "1-2"
1487
+ # # ]
1488
+ #
1489
+ # @example
1490
+ # Polars::Series.new([1, nil, 2]).str.join("-", ignore_nulls: false)
1491
+ # # =>
1492
+ # # shape: (1,)
1493
+ # # Series: '' [str]
1494
+ # # [
1495
+ # # null
1496
+ # # ]
1497
+ def join(delimiter = "", ignore_nulls: true)
1498
+ super
1499
+ end
1500
+
1501
+ # Returns string values with all regular expression meta characters escaped.
1502
+ #
1503
+ # @return [Series]
1504
+ #
1505
+ # @example
1506
+ # Polars::Series.new(["abc", "def", nil, "abc(\\w+)"]).str.escape_regex
1507
+ # # =>
1508
+ # # shape: (4,)
1509
+ # # Series: '' [str]
1510
+ # # [
1511
+ # # "abc"
1512
+ # # "def"
1513
+ # # null
1514
+ # # "abc\(\\w\+\)"
1515
+ # # ]
1516
+ def escape_regex
1517
+ super
1518
+ end
1519
+
1520
+ # Returns the Unicode normal form of the string values.
1521
+ #
1522
+ # This uses the forms described in Unicode Standard Annex 15: <https://www.unicode.org/reports/tr15/>.
1523
+ #
1524
+ # @param form ['NFC', 'NFKC', 'NFD', 'NFKD']
1525
+ # Unicode form to use.
1526
+ #
1527
+ # @return [Series]
1528
+ #
1529
+ # @example
1530
+ # s = Polars::Series.new(["01²", "KADOKAWA"])
1531
+ # s.str.normalize("NFC")
1532
+ # # =>
1533
+ # # shape: (2,)
1534
+ # # Series: '' [str]
1535
+ # # [
1536
+ # # "01²"
1537
+ # # "KADOKAWA"
1538
+ # # ]
1539
+ #
1540
+ # @example
1541
+ # s.str.normalize("NFKC")
1542
+ # # =>
1543
+ # # shape: (2,)
1544
+ # # Series: '' [str]
1545
+ # # [
1546
+ # # "012"
1547
+ # # "KADOKAWA"
1548
+ # # ]
1549
+ def normalize(form = "NFC")
1550
+ super
1551
+ end
880
1552
  end
881
1553
  end