polars-df 0.2.0-x86_64-linux

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 (46) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +3 -0
  3. data/CHANGELOG.md +33 -0
  4. data/Cargo.lock +2230 -0
  5. data/Cargo.toml +10 -0
  6. data/LICENSE-THIRD-PARTY.txt +38828 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.md +91 -0
  9. data/lib/polars/3.0/polars.so +0 -0
  10. data/lib/polars/3.1/polars.so +0 -0
  11. data/lib/polars/3.2/polars.so +0 -0
  12. data/lib/polars/batched_csv_reader.rb +96 -0
  13. data/lib/polars/cat_expr.rb +52 -0
  14. data/lib/polars/cat_name_space.rb +54 -0
  15. data/lib/polars/convert.rb +100 -0
  16. data/lib/polars/data_frame.rb +4833 -0
  17. data/lib/polars/data_types.rb +122 -0
  18. data/lib/polars/date_time_expr.rb +1418 -0
  19. data/lib/polars/date_time_name_space.rb +1484 -0
  20. data/lib/polars/dynamic_group_by.rb +52 -0
  21. data/lib/polars/exceptions.rb +20 -0
  22. data/lib/polars/expr.rb +5307 -0
  23. data/lib/polars/expr_dispatch.rb +22 -0
  24. data/lib/polars/functions.rb +453 -0
  25. data/lib/polars/group_by.rb +558 -0
  26. data/lib/polars/io.rb +814 -0
  27. data/lib/polars/lazy_frame.rb +2442 -0
  28. data/lib/polars/lazy_functions.rb +1195 -0
  29. data/lib/polars/lazy_group_by.rb +93 -0
  30. data/lib/polars/list_expr.rb +610 -0
  31. data/lib/polars/list_name_space.rb +346 -0
  32. data/lib/polars/meta_expr.rb +54 -0
  33. data/lib/polars/rolling_group_by.rb +35 -0
  34. data/lib/polars/series.rb +3730 -0
  35. data/lib/polars/slice.rb +104 -0
  36. data/lib/polars/string_expr.rb +972 -0
  37. data/lib/polars/string_name_space.rb +690 -0
  38. data/lib/polars/struct_expr.rb +100 -0
  39. data/lib/polars/struct_name_space.rb +64 -0
  40. data/lib/polars/utils.rb +192 -0
  41. data/lib/polars/version.rb +4 -0
  42. data/lib/polars/when.rb +16 -0
  43. data/lib/polars/when_then.rb +19 -0
  44. data/lib/polars-df.rb +1 -0
  45. data/lib/polars.rb +50 -0
  46. metadata +89 -0
@@ -0,0 +1,690 @@
1
+ module Polars
2
+ # Series.str namespace.
3
+ class StringNameSpace
4
+ include ExprDispatch
5
+
6
+ self._accessor = "str"
7
+
8
+ # @private
9
+ def initialize(series)
10
+ self._s = series._s
11
+ end
12
+
13
+ # Parse a Series of dtype Utf8 to a Date/Datetime Series.
14
+ #
15
+ # @param datatype [Symbol]
16
+ # `:date`, `:dateime`, or `:time`.
17
+ # @param fmt [String]
18
+ # Format to use, refer to the
19
+ # [chrono strftime documentation](https://docs.rs/chrono/latest/chrono/format/strftime/index.html)
20
+ # for specification. Example: `"%y-%m-%d"`.
21
+ # @param strict [Boolean]
22
+ # Raise an error if any conversion fails.
23
+ # @param exact [Boolean]
24
+ # - If true, require an exact format match.
25
+ # - If false, allow the format to match anywhere in the target string.
26
+ #
27
+ # @return [Series]
28
+ #
29
+ # @example
30
+ # s = Polars::Series.new(
31
+ # "date",
32
+ # [
33
+ # "2021-04-22",
34
+ # "2022-01-04 00:00:00",
35
+ # "01/31/22",
36
+ # "Sun Jul 8 00:34:60 2001"
37
+ # ]
38
+ # )
39
+ # s.to_frame.with_column(
40
+ # Polars.col("date")
41
+ # .str.strptime(:date, "%F", strict: false)
42
+ # .fill_null(
43
+ # Polars.col("date").str.strptime(:date, "%F %T", strict: false)
44
+ # )
45
+ # .fill_null(Polars.col("date").str.strptime(:date, "%D", strict: false))
46
+ # .fill_null(Polars.col("date").str.strptime(:date, "%c", strict: false))
47
+ # )
48
+ # # =>
49
+ # # shape: (4, 1)
50
+ # # ┌────────────┐
51
+ # # │ date │
52
+ # # │ --- │
53
+ # # │ date │
54
+ # # ╞════════════╡
55
+ # # │ 2021-04-22 │
56
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┤
57
+ # # │ 2022-01-04 │
58
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┤
59
+ # # │ 2022-01-31 │
60
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┤
61
+ # # │ 2001-07-08 │
62
+ # # └────────────┘
63
+ def strptime(datatype, fmt = nil, strict: true, exact: true, cache: true, tz_aware: false)
64
+ super
65
+ end
66
+
67
+ # Get length of the string values in the Series (as number of bytes).
68
+ #
69
+ # @return [Series]
70
+ #
71
+ # @note
72
+ # The returned lengths are equal to the number of bytes in the UTF8 string. If you
73
+ # need the length in terms of the number of characters, use `n_chars` instead.
74
+ #
75
+ # @example
76
+ # s = Polars::Series.new(["Café", nil, "345", "東京"])
77
+ # s.str.lengths
78
+ # # =>
79
+ # # shape: (4,)
80
+ # # Series: '' [u32]
81
+ # # [
82
+ # # 5
83
+ # # null
84
+ # # 3
85
+ # # 6
86
+ # # ]
87
+ def lengths
88
+ super
89
+ end
90
+
91
+ # Get length of the string values in the Series (as number of chars).
92
+ #
93
+ # @return [Series]
94
+ #
95
+ # @note
96
+ # If you know that you are working with ASCII text, `lengths` will be
97
+ # equivalent, and faster (returns length in terms of the number of bytes).
98
+ #
99
+ # @example
100
+ # s = Polars::Series.new(["Café", nil, "345", "東京"])
101
+ # s.str.n_chars
102
+ # # =>
103
+ # # shape: (4,)
104
+ # # Series: '' [u32]
105
+ # # [
106
+ # # 4
107
+ # # null
108
+ # # 3
109
+ # # 2
110
+ # # ]
111
+ def n_chars
112
+ super
113
+ end
114
+
115
+ # Vertically concat the values in the Series to a single string value.
116
+ #
117
+ # @param delimiter [String]
118
+ # The delimiter to insert between consecutive string values.
119
+ #
120
+ # @return [Series]
121
+ #
122
+ # @example
123
+ # Polars::Series.new([1, nil, 2]).str.concat("-")[0]
124
+ # # => "1-null-2"
125
+ def concat(delimiter = "-")
126
+ super
127
+ end
128
+
129
+ # Check if strings in Series contain a substring that matches a regex.
130
+ #
131
+ # @param pattern [String]
132
+ # A valid regex pattern.
133
+ # @param literal [Boolean]
134
+ # Treat pattern as a literal string.
135
+ #
136
+ # @return [Series]
137
+ #
138
+ # @example
139
+ # s = Polars::Series.new(["Crab", "cat and dog", "rab$bit", nil])
140
+ # s.str.contains("cat|bit")
141
+ # # =>
142
+ # # shape: (4,)
143
+ # # Series: '' [bool]
144
+ # # [
145
+ # # false
146
+ # # true
147
+ # # true
148
+ # # null
149
+ # # ]
150
+ #
151
+ # @example
152
+ # s.str.contains("rab$", literal: true)
153
+ # # =>
154
+ # # shape: (4,)
155
+ # # Series: '' [bool]
156
+ # # [
157
+ # # false
158
+ # # false
159
+ # # true
160
+ # # null
161
+ # # ]
162
+ def contains(pattern, literal: false)
163
+ super
164
+ end
165
+
166
+ # Check if string values end with a substring.
167
+ #
168
+ # @param sub [String]
169
+ # Suffix substring.
170
+ #
171
+ # @return [Series]
172
+ #
173
+ # @example
174
+ # s = Polars::Series.new("fruits", ["apple", "mango", nil])
175
+ # s.str.ends_with("go")
176
+ # # =>
177
+ # # shape: (3,)
178
+ # # Series: 'fruits' [bool]
179
+ # # [
180
+ # # false
181
+ # # true
182
+ # # null
183
+ # # ]
184
+ def ends_with(sub)
185
+ super
186
+ end
187
+
188
+ # Check if string values start with a substring.
189
+ #
190
+ # @param sub [String]
191
+ # Prefix substring.
192
+ #
193
+ # @return [Series]
194
+ #
195
+ # @example
196
+ # s = Polars::Series.new("fruits", ["apple", "mango", nil])
197
+ # s.str.starts_with("app")
198
+ # # =>
199
+ # # shape: (3,)
200
+ # # Series: 'fruits' [bool]
201
+ # # [
202
+ # # true
203
+ # # false
204
+ # # null
205
+ # # ]
206
+ def starts_with(sub)
207
+ super
208
+ end
209
+
210
+ # Decode a value using the provided encoding.
211
+ #
212
+ # @param encoding ["hex", "base64"]
213
+ # The encoding to use.
214
+ # @param strict [Boolean]
215
+ # How to handle invalid inputs:
216
+ #
217
+ # - `true`: An error will be thrown if unable to decode a value.
218
+ # - `false`: Unhandled values will be replaced with `nil`.
219
+ #
220
+ # @return [Series]
221
+ #
222
+ # @example
223
+ # s = Polars::Series.new(["666f6f", "626172", nil])
224
+ # s.str.decode("hex")
225
+ # # =>
226
+ # # shape: (3,)
227
+ # # Series: '' [str]
228
+ # # [
229
+ # # "foo"
230
+ # # "bar"
231
+ # # null
232
+ # # ]
233
+ def decode(encoding, strict: false)
234
+ super
235
+ end
236
+
237
+ # Encode a value using the provided encoding.
238
+ #
239
+ # @param encoding ["hex", "base64"]
240
+ # The encoding to use.
241
+ #
242
+ # @return [Series]
243
+ #
244
+ # @example
245
+ # s = Polars::Series.new(["foo", "bar", nil])
246
+ # s.str.encode("hex")
247
+ # # =>
248
+ # # shape: (3,)
249
+ # # Series: '' [str]
250
+ # # [
251
+ # # "666f6f"
252
+ # # "626172"
253
+ # # null
254
+ # # ]
255
+ def encode(encoding)
256
+ super
257
+ end
258
+
259
+ # Extract the first match of json string with provided JSONPath expression.
260
+ #
261
+ # Throw errors if encounter invalid json strings.
262
+ # All return value will be casted to Utf8 regardless of the original value.
263
+ #
264
+ # Documentation on JSONPath standard can be found
265
+ # [here](https://goessner.net/articles/JsonPath/).
266
+ #
267
+ # @param json_path [String]
268
+ # A valid JSON path query string.
269
+ #
270
+ # @return [Series]
271
+ #
272
+ # @example
273
+ # df = Polars::DataFrame.new(
274
+ # {"json_val" => ['{"a":"1"}', nil, '{"a":2}', '{"a":2.1}', '{"a":true}']}
275
+ # )
276
+ # df.select(Polars.col("json_val").str.json_path_match("$.a"))[0.., 0]
277
+ # # =>
278
+ # # shape: (5,)
279
+ # # Series: 'json_val' [str]
280
+ # # [
281
+ # # "1"
282
+ # # null
283
+ # # "2"
284
+ # # "2.1"
285
+ # # "true"
286
+ # # ]
287
+ def json_path_match(json_path)
288
+ super
289
+ end
290
+
291
+ # Extract the target capture group from provided patterns.
292
+ #
293
+ # @param pattern [String]
294
+ # A valid regex pattern
295
+ # @param group_index [Integer]
296
+ # Index of the targeted capture group.
297
+ # Group 0 mean the whole pattern, first group begin at index 1
298
+ # Default to the first capture group
299
+ #
300
+ # @return [Series]
301
+ #
302
+ # @example
303
+ # df = Polars::DataFrame.new({"foo" => ["123 bla 45 asd", "xyz 678 910t"]})
304
+ # df.select([Polars.col("foo").str.extract('(\d+)')])
305
+ # # =>
306
+ # # shape: (2, 1)
307
+ # # ┌─────┐
308
+ # # │ foo │
309
+ # # │ --- │
310
+ # # │ str │
311
+ # # ╞═════╡
312
+ # # │ 123 │
313
+ # # ├╌╌╌╌╌┤
314
+ # # │ 678 │
315
+ # # └─────┘
316
+ def extract(pattern, group_index: 1)
317
+ super
318
+ end
319
+
320
+ # Extracts all matches for the given regex pattern.
321
+ #
322
+ # Extract each successive non-overlapping regex match in an individual string as
323
+ # an array
324
+ #
325
+ # @param pattern [String]
326
+ # A valid regex pattern
327
+ #
328
+ # @return [Series]
329
+ #
330
+ # @example
331
+ # s = Polars::Series.new("foo", ["123 bla 45 asd", "xyz 678 910t"])
332
+ # s.str.extract_all('(\d+)')
333
+ # # =>
334
+ # # shape: (2,)
335
+ # # Series: 'foo' [list]
336
+ # # [
337
+ # # ["123", "45"]
338
+ # # ["678", "910"]
339
+ # # ]
340
+ def extract_all(pattern)
341
+ super
342
+ end
343
+
344
+ # Count all successive non-overlapping regex matches.
345
+ #
346
+ # @param pattern [String]
347
+ # A valid regex pattern
348
+ #
349
+ # @return [Series]
350
+ #
351
+ # @example
352
+ # s = Polars::Series.new("foo", ["123 bla 45 asd", "xyz 678 910t"])
353
+ # s.str.count_match('\d')
354
+ # # =>
355
+ # # shape: (2,)
356
+ # # Series: 'foo' [u32]
357
+ # # [
358
+ # # 5
359
+ # # 6
360
+ # # ]
361
+ def count_match(pattern)
362
+ super
363
+ end
364
+
365
+ # Split the string by a substring.
366
+ #
367
+ # @param by [String]
368
+ # Substring to split by.
369
+ # @param inclusive [Boolean]
370
+ # If true, include the split character/string in the results.
371
+ #
372
+ # @return [Series]
373
+ def split(by, inclusive: false)
374
+ super
375
+ end
376
+
377
+ # Split the string by a substring using `n` splits.
378
+ #
379
+ # Results in a struct of `n+1` fields.
380
+ #
381
+ # If it cannot make `n` splits, the remaining field elements will be null.
382
+ #
383
+ # @param by [String]
384
+ # Substring to split by.
385
+ # @param n [Integer]
386
+ # Number of splits to make.
387
+ # @param inclusive [Boolean]
388
+ # If true, include the split character/string in the results.
389
+ #
390
+ # @return [Series]
391
+ #
392
+ # @example
393
+ # df = Polars::DataFrame.new({"x" => ["a_1", nil, "c", "d_4"]})
394
+ # df["x"].str.split_exact("_", 1).alias("fields")
395
+ # # =>
396
+ # # shape: (4,)
397
+ # # Series: 'fields' [struct[2]]
398
+ # # [
399
+ # # {"a","1"}
400
+ # # {null,null}
401
+ # # {"c",null}
402
+ # # {"d","4"}
403
+ # # ]
404
+ #
405
+ # @example Split string values in column x in exactly 2 parts and assign each part to a new column.
406
+ # df["x"]
407
+ # .str.split_exact("_", 1)
408
+ # .struct.rename_fields(["first_part", "second_part"])
409
+ # .alias("fields")
410
+ # .to_frame
411
+ # .unnest("fields")
412
+ # # =>
413
+ # # shape: (4, 2)
414
+ # # ┌────────────┬─────────────┐
415
+ # # │ first_part ┆ second_part │
416
+ # # │ --- ┆ --- │
417
+ # # │ str ┆ str │
418
+ # # ╞════════════╪═════════════╡
419
+ # # │ a ┆ 1 │
420
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
421
+ # # │ null ┆ null │
422
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
423
+ # # │ c ┆ null │
424
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
425
+ # # │ d ┆ 4 │
426
+ # # └────────────┴─────────────┘
427
+ def split_exact(by, n, inclusive: false)
428
+ super
429
+ end
430
+
431
+ # Split the string by a substring, restricted to returning at most `n` items.
432
+ #
433
+ # If the number of possible splits is less than `n-1`, the remaining field
434
+ # elements will be null. If the number of possible splits is `n-1` or greater,
435
+ # the last (nth) substring will contain the remainder of the string.
436
+ #
437
+ # @param by [String]
438
+ # Substring to split by.
439
+ # @param n [Integer]
440
+ # Max number of items to return.
441
+ #
442
+ # @return [Series]
443
+ #
444
+ # @example
445
+ # df = Polars::DataFrame.new({"s" => ["foo bar", nil, "foo-bar", "foo bar baz"]})
446
+ # df["s"].str.splitn(" ", 2).alias("fields")
447
+ # # =>
448
+ # # shape: (4,)
449
+ # # Series: 'fields' [struct[2]]
450
+ # # [
451
+ # # {"foo","bar"}
452
+ # # {null,null}
453
+ # # {"foo-bar",null}
454
+ # # {"foo","bar baz"}
455
+ # # ]
456
+ #
457
+ # @example Split string values in column s in exactly 2 parts and assign each part to a new column.
458
+ # df["s"]
459
+ # .str.splitn(" ", 2)
460
+ # .struct.rename_fields(["first_part", "second_part"])
461
+ # .alias("fields")
462
+ # .to_frame
463
+ # .unnest("fields")
464
+ # # =>
465
+ # # shape: (4, 2)
466
+ # # ┌────────────┬─────────────┐
467
+ # # │ first_part ┆ second_part │
468
+ # # │ --- ┆ --- │
469
+ # # │ str ┆ str │
470
+ # # ╞════════════╪═════════════╡
471
+ # # │ foo ┆ bar │
472
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
473
+ # # │ null ┆ null │
474
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
475
+ # # │ foo-bar ┆ null │
476
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
477
+ # # │ foo ┆ bar baz │
478
+ # # └────────────┴─────────────┘
479
+ def splitn(by, n)
480
+ s = Utils.wrap_s(_s)
481
+ s.to_frame.select(Polars.col(s.name).str.splitn(by, n)).to_series
482
+ end
483
+
484
+ # Replace first matching regex/literal substring with a new string value.
485
+ #
486
+ # @param pattern [String]
487
+ # A valid regex pattern.
488
+ # @param value [String]
489
+ # Substring to replace.
490
+ # @param literal [Boolean]
491
+ # Treat pattern as a literal string.
492
+ #
493
+ # @return [Series]
494
+ #
495
+ # @example
496
+ # s = Polars::Series.new(["123abc", "abc456"])
497
+ # s.str.replace('abc\b', "ABC")
498
+ # # =>
499
+ # # shape: (2,)
500
+ # # Series: '' [str]
501
+ # # [
502
+ # # "123ABC"
503
+ # # "abc456"
504
+ # # ]
505
+ def replace(pattern, value, literal: false)
506
+ super
507
+ end
508
+
509
+ # Replace all matching regex/literal substrings with a new string value.
510
+ #
511
+ # @param pattern [String]
512
+ # A valid regex pattern.
513
+ # @param value [String]
514
+ # Substring to replace.
515
+ # @param literal [Boolean]
516
+ # Treat pattern as a literal string.
517
+ #
518
+ # @return [Series]
519
+ #
520
+ # @example
521
+ # df = Polars::Series.new(["abcabc", "123a123"])
522
+ # df.str.replace_all("a", "-")
523
+ # # =>
524
+ # # shape: (2,)
525
+ # # Series: '' [str]
526
+ # # [
527
+ # # "-bc-bc"
528
+ # # "123-123"
529
+ # # ]
530
+ def replace_all(pattern, value, literal: false)
531
+ super
532
+ end
533
+
534
+ # Remove leading and trailing whitespace.
535
+ #
536
+ # @param matches [String, nil]
537
+ # An optional single character that should be trimmed
538
+ #
539
+ # @return [Series]
540
+ def strip(matches = nil)
541
+ super
542
+ end
543
+
544
+ # Remove leading whitespace.
545
+ #
546
+ # @param matches [String, nil]
547
+ # An optional single character that should be trimmed
548
+ #
549
+ # @return [Series]
550
+ def lstrip(matches = nil)
551
+ super
552
+ end
553
+
554
+ # Remove trailing whitespace.
555
+ #
556
+ # @param matches [String, nil]
557
+ # An optional single character that should be trimmed
558
+ #
559
+ # @return [Series]
560
+ def rstrip(matches = nil)
561
+ super
562
+ end
563
+
564
+ # Fills the string with zeroes.
565
+ #
566
+ # Return a copy of the string left filled with ASCII '0' digits to make a string
567
+ # of length width.
568
+ #
569
+ # A leading sign prefix ('+'/'-') is handled by inserting the padding after the
570
+ # sign character rather than before. The original string is returned if width is
571
+ # less than or equal to `s.length`.
572
+ #
573
+ # @param alignment [Integer]
574
+ # Fill the value up to this length.
575
+ #
576
+ # @return [Series]
577
+ def zfill(alignment)
578
+ super
579
+ end
580
+
581
+ # Return the string left justified in a string of length `width`.
582
+ #
583
+ # Padding is done using the specified `fillchar`. The original string is
584
+ # returned if `width` is less than or equal to `s.length`.
585
+ #
586
+ # @param width [Integer]
587
+ # Justify left to this length.
588
+ # @param fillchar [String]
589
+ # Fill with this ASCII character.
590
+ #
591
+ # @return [Series]
592
+ #
593
+ # @example
594
+ # s = Polars::Series.new("a", ["cow", "monkey", nil, "hippopotamus"])
595
+ # s.str.ljust(8, "*")
596
+ # # =>
597
+ # # shape: (4,)
598
+ # # Series: 'a' [str]
599
+ # # [
600
+ # # "cow*****"
601
+ # # "monkey**"
602
+ # # null
603
+ # # "hippopotamus"
604
+ # # ]
605
+ def ljust(width, fillchar = " ")
606
+ super
607
+ end
608
+
609
+ # Return the string right justified in a string of length `width`.
610
+ #
611
+ # Padding is done using the specified `fillchar`. The original string is
612
+ # returned if `width` is less than or equal to `s.length`.
613
+ #
614
+ # @param width [Integer]
615
+ # Justify right to this length.
616
+ # @param fillchar [String]
617
+ # Fill with this ASCII character.
618
+ #
619
+ # @return [Series]
620
+ #
621
+ # @example
622
+ # s = Polars::Series.new("a", ["cow", "monkey", nil, "hippopotamus"])
623
+ # s.str.rjust(8, "*")
624
+ # # =>
625
+ # # shape: (4,)
626
+ # # Series: 'a' [str]
627
+ # # [
628
+ # # "*****cow"
629
+ # # "**monkey"
630
+ # # null
631
+ # # "hippopotamus"
632
+ # # ]
633
+ def rjust(width, fillchar = " ")
634
+ super
635
+ end
636
+
637
+ # Modify the strings to their lowercase equivalent.
638
+ #
639
+ # @return [Series]
640
+ def to_lowercase
641
+ super
642
+ end
643
+
644
+ # Modify the strings to their uppercase equivalent.
645
+ #
646
+ # @return [Series]
647
+ def to_uppercase
648
+ super
649
+ end
650
+
651
+ # Create subslices of the string values of a Utf8 Series.
652
+ #
653
+ # @param offset [Integer]
654
+ # Start index. Negative indexing is supported.
655
+ # @param length [Integer]
656
+ # Length of the slice. If set to `nil` (default), the slice is taken to the
657
+ # end of the string.
658
+ #
659
+ # @return [Series]
660
+ #
661
+ # @example
662
+ # s = Polars::Series.new("s", ["pear", nil, "papaya", "dragonfruit"])
663
+ # s.str.slice(-3)
664
+ # # =>
665
+ # # shape: (4,)
666
+ # # Series: 's' [str]
667
+ # # [
668
+ # # "ear"
669
+ # # null
670
+ # # "aya"
671
+ # # "uit"
672
+ # # ]
673
+ #
674
+ # @example Using the optional `length` parameter
675
+ # s.str.slice(4, 3)
676
+ # # =>
677
+ # # shape: (4,)
678
+ # # Series: 's' [str]
679
+ # # [
680
+ # # ""
681
+ # # null
682
+ # # "ya"
683
+ # # "onf"
684
+ # # ]
685
+ def slice(offset, length = nil)
686
+ s = Utils.wrap_s(_s)
687
+ s.to_frame.select(Polars.col(s.name).str.slice(offset, length)).to_series
688
+ end
689
+ end
690
+ end