polars-df 0.2.0-aarch64-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,3730 @@
1
+ module Polars
2
+ # A Series represents a single column in a polars DataFrame.
3
+ class Series
4
+ include ExprDispatch
5
+
6
+ # Create a new Series.
7
+ #
8
+ # @param name [String, Array, nil]
9
+ # Name of the series. Will be used as a column name when used in a DataFrame.
10
+ # When not specified, name is set to an empty string.
11
+ # @param values [Array, nil]
12
+ # One-dimensional data in various forms. Supported are: Array and Series.
13
+ # @param dtype [Symbol, nil]
14
+ # Polars dtype of the Series data. If not specified, the dtype is inferred.
15
+ # @param strict [Boolean]
16
+ # Throw error on numeric overflow.
17
+ # @param nan_to_null [Boolean]
18
+ # Not used.
19
+ # @param dtype_if_empty [Symbol, nil]
20
+ # If no dtype is specified and values contains `nil` or an empty array,
21
+ # set the Polars dtype of the Series data. If not specified, Float32 is used.
22
+ #
23
+ # @example Constructing a Series by specifying name and values positionally:
24
+ # s = Polars::Series.new("a", [1, 2, 3])
25
+ #
26
+ # @example Notice that the dtype is automatically inferred as a polars `Int64`:
27
+ # s.dtype
28
+ # # => Polars::Int64
29
+ #
30
+ # @example Constructing a Series with a specific dtype:
31
+ # s2 = Polars::Series.new("a", [1, 2, 3], dtype: :f32)
32
+ #
33
+ # @example It is possible to construct a Series with values as the first positional argument. This syntax considered an anti-pattern, but it can be useful in certain scenarios. You must specify any other arguments through keywords.
34
+ # s3 = Polars::Series.new([1, 2, 3])
35
+ def initialize(name = nil, values = nil, dtype: nil, strict: true, nan_to_null: false, dtype_if_empty: nil)
36
+ # Handle case where values are passed as the first argument
37
+ if !name.nil? && !name.is_a?(String)
38
+ if values.nil?
39
+ values = name
40
+ name = nil
41
+ else
42
+ raise ArgumentError, "Series name must be a string."
43
+ end
44
+ end
45
+
46
+ name = "" if name.nil?
47
+
48
+ # TODO improve
49
+ if values.is_a?(Range) && values.begin.is_a?(String)
50
+ values = values.to_a
51
+ end
52
+
53
+ if values.nil?
54
+ self._s = sequence_to_rbseries(name, [], dtype: dtype, dtype_if_empty: dtype_if_empty)
55
+ elsif values.is_a?(Series)
56
+ self._s = series_to_rbseries(name, values)
57
+ elsif values.is_a?(Range)
58
+ self._s =
59
+ Polars.arange(
60
+ values.first,
61
+ values.last + (values.exclude_end? ? 0 : 1),
62
+ step: 1,
63
+ eager: true,
64
+ dtype: dtype
65
+ )
66
+ .rename(name, in_place: true)
67
+ ._s
68
+ elsif values.is_a?(Array)
69
+ self._s = sequence_to_rbseries(name, values, dtype: dtype, strict: strict, dtype_if_empty: dtype_if_empty)
70
+ else
71
+ raise ArgumentError, "Series constructor called with unsupported type; got #{values.class.name}"
72
+ end
73
+ end
74
+
75
+ # @private
76
+ def self._from_rbseries(s)
77
+ series = Series.allocate
78
+ series._s = s
79
+ series
80
+ end
81
+
82
+ # Get the data type of this Series.
83
+ #
84
+ # @return [Symbol]
85
+ def dtype
86
+ _s.dtype
87
+ end
88
+
89
+ # Get flags that are set on the Series.
90
+ #
91
+ # @return [Hash]
92
+ def flags
93
+ {
94
+ "SORTED_ASC" => _s.is_sorted_flag,
95
+ "SORTED_DESC" => _s.is_sorted_reverse_flag
96
+ }
97
+ end
98
+
99
+ # Get the inner dtype in of a List typed Series.
100
+ #
101
+ # @return [Symbol]
102
+ def inner_dtype
103
+ _s.inner_dtype
104
+ end
105
+
106
+ # Get the name of this Series.
107
+ #
108
+ # @return [String]
109
+ def name
110
+ _s.name
111
+ end
112
+
113
+ # Shape of this Series.
114
+ #
115
+ # @return [Array]
116
+ def shape
117
+ [_s.len]
118
+ end
119
+
120
+ # Get the time unit of underlying Datetime Series as `"ns"`, `"us"`, or `"ms"`.
121
+ #
122
+ # @return [String]
123
+ def time_unit
124
+ _s.time_unit
125
+ end
126
+
127
+ # Returns a string representing the Series.
128
+ #
129
+ # @return [String]
130
+ def to_s
131
+ _s.to_s
132
+ end
133
+ alias_method :inspect, :to_s
134
+
135
+ # Bitwise AND.
136
+ #
137
+ # @return [Series]
138
+ def &(other)
139
+ if !other.is_a?(Series)
140
+ other = Series.new([other])
141
+ end
142
+ Utils.wrap_s(_s.bitand(other._s))
143
+ end
144
+
145
+ # Bitwise OR.
146
+ #
147
+ # @return [Series]
148
+ def |(other)
149
+ if !other.is_a?(Series)
150
+ other = Series.new([other])
151
+ end
152
+ Utils.wrap_s(_s.bitor(other._s))
153
+ end
154
+
155
+ # Bitwise XOR.
156
+ #
157
+ # @return [Series]
158
+ def ^(other)
159
+ if !other.is_a?(Series)
160
+ other = Series.new([other])
161
+ end
162
+ Utils.wrap_s(_s.bitxor(other._s))
163
+ end
164
+
165
+ # Equal.
166
+ #
167
+ # @return [Series]
168
+ def ==(other)
169
+ _comp(other, :eq)
170
+ end
171
+
172
+ # Not equal.
173
+ #
174
+ # @return [Series]
175
+ def !=(other)
176
+ _comp(other, :neq)
177
+ end
178
+
179
+ # Greater than.
180
+ #
181
+ # @return [Series]
182
+ def >(other)
183
+ _comp(other, :gt)
184
+ end
185
+
186
+ # Less than.
187
+ #
188
+ # @return [Series]
189
+ def <(other)
190
+ _comp(other, :lt)
191
+ end
192
+
193
+ # Greater than or equal.
194
+ #
195
+ # @return [Series]
196
+ def >=(other)
197
+ _comp(other, :gt_eq)
198
+ end
199
+
200
+ # Less than or equal.
201
+ #
202
+ # @return [Series]
203
+ def <=(other)
204
+ _comp(other, :lt_eq)
205
+ end
206
+
207
+ # Performs addition.
208
+ #
209
+ # @return [Series]
210
+ def +(other)
211
+ _arithmetic(other, :add)
212
+ end
213
+
214
+ # Performs subtraction.
215
+ #
216
+ # @return [Series]
217
+ def -(other)
218
+ _arithmetic(other, :sub)
219
+ end
220
+
221
+ # Performs multiplication.
222
+ #
223
+ # @return [Series]
224
+ def *(other)
225
+ _arithmetic(other, :mul)
226
+ end
227
+
228
+ # Performs division.
229
+ #
230
+ # @return [Series]
231
+ def /(other)
232
+ _arithmetic(other, :div)
233
+ end
234
+
235
+ # Returns the modulo.
236
+ #
237
+ # @return [Series]
238
+ def %(other)
239
+ if is_datelike
240
+ raise ArgumentError, "first cast to integer before applying modulo on datelike dtypes"
241
+ end
242
+ _arithmetic(other, :rem)
243
+ end
244
+
245
+ # Raises to the power of exponent.
246
+ #
247
+ # @return [Series]
248
+ def **(power)
249
+ if is_datelike
250
+ raise ArgumentError, "first cast to integer before raising datelike dtypes to a power"
251
+ end
252
+ to_frame.select(Polars.col(name).pow(power)).to_series
253
+ end
254
+
255
+ # Performs negation.
256
+ #
257
+ # @return [Series]
258
+ def -@
259
+ 0 - self
260
+ end
261
+
262
+ # Returns elements of the Series.
263
+ #
264
+ # @return [Object]
265
+ def [](item)
266
+ if item.is_a?(Integer)
267
+ return _s.get_idx(item)
268
+ end
269
+
270
+ if item.is_a?(Range)
271
+ return Slice.new(self).apply(item)
272
+ end
273
+
274
+ raise ArgumentError, "Cannot get item of type: #{item.class.name}"
275
+ end
276
+
277
+ # Sets an element of the Series.
278
+ #
279
+ # @return [Object]
280
+ def []=(key, value)
281
+ if value.is_a?(Array)
282
+ if is_numeric || is_datelike
283
+ set_at_idx(key, value)
284
+ return
285
+ end
286
+ raise ArgumentError, "cannot set Series of dtype: #{dtype} with list/tuple as value; use a scalar value"
287
+ end
288
+
289
+ if key.is_a?(Series)
290
+ if key.dtype == :bool
291
+ self._s = set(key, value)._s
292
+ elsif key.dtype == :u64
293
+ self._s = set_at_idx(key.cast(:u32), value)._s
294
+ elsif key.dtype == :u32
295
+ self._s = set_at_idx(key, value)._s
296
+ else
297
+ raise Todo
298
+ end
299
+ end
300
+
301
+ if key.is_a?(Array)
302
+ s = Utils.wrap_s(sequence_to_rbseries("", key, dtype: :u32))
303
+ self[s] = value
304
+ elsif key.is_a?(Integer)
305
+ # TODO fix
306
+ # self[[key]] = value
307
+ set_at_idx(key, value)
308
+ else
309
+ raise ArgumentError, "cannot use #{key} for indexing"
310
+ end
311
+ end
312
+
313
+ # Return an estimation of the total (heap) allocated size of the Series.
314
+ #
315
+ # Estimated size is given in the specified unit (bytes by default).
316
+ #
317
+ # This estimation is the sum of the size of its buffers, validity, including
318
+ # nested arrays. Multiple arrays may share buffers and bitmaps. Therefore, the
319
+ # size of 2 arrays is not the sum of the sizes computed from this function. In
320
+ # particular, StructArray's size is an upper bound.
321
+ #
322
+ # When an array is sliced, its allocated size remains constant because the buffer
323
+ # unchanged. However, this function will yield a smaller number. This is because
324
+ # this function returns the visible size of the buffer, not its total capacity.
325
+ #
326
+ # FFI buffers are included in this estimation.
327
+ #
328
+ # @param unit ["b", "kb", "mb", "gb", "tb"]
329
+ # Scale the returned size to the given unit.
330
+ #
331
+ # @return [Numeric]
332
+ #
333
+ # @example
334
+ # s = Polars::Series.new("values", 1..1_000_000, dtype: :u32)
335
+ # s.estimated_size
336
+ # # => 4000000
337
+ # s.estimated_size("mb")
338
+ # # => 3.814697265625
339
+ def estimated_size(unit = "b")
340
+ sz = _s.estimated_size
341
+ Utils.scale_bytes(sz, to: unit)
342
+ end
343
+
344
+ # Compute the square root of the elements.
345
+ #
346
+ # @return [Series]
347
+ def sqrt
348
+ self**0.5
349
+ end
350
+
351
+ # Check if any boolean value in the column is `true`.
352
+ #
353
+ # @return [Boolean]
354
+ def any
355
+ to_frame.select(Polars.col(name).any).to_series[0]
356
+ end
357
+
358
+ # Check if all boolean values in the column are `true`.
359
+ #
360
+ # @return [Boolean]
361
+ def all
362
+ to_frame.select(Polars.col(name).all).to_series[0]
363
+ end
364
+
365
+ # Compute the logarithm to a given base.
366
+ #
367
+ # @param base [Float]
368
+ # Given base, defaults to `Math::E`.
369
+ #
370
+ # @return [Series]
371
+ def log(base = Math::E)
372
+ super
373
+ end
374
+
375
+ # Compute the base 10 logarithm of the input array, element-wise.
376
+ #
377
+ # @return [Series]
378
+ def log10
379
+ super
380
+ end
381
+
382
+ # Compute the exponential, element-wise.
383
+ #
384
+ # @return [Series]
385
+ def exp
386
+ super
387
+ end
388
+
389
+ # Create a new Series that copies data from this Series without null values.
390
+ #
391
+ # @return [Series]
392
+ def drop_nulls
393
+ super
394
+ end
395
+
396
+ # Drop NaN values.
397
+ #
398
+ # @return [Series]
399
+ def drop_nans
400
+ super
401
+ end
402
+
403
+ # Cast this Series to a DataFrame.
404
+ #
405
+ # @return [DataFrame]
406
+ def to_frame
407
+ Utils.wrap_df(RbDataFrame.new([_s]))
408
+ end
409
+
410
+ # Quick summary statistics of a series.
411
+ #
412
+ # Series with mixed datatypes will return summary statistics for the datatype of
413
+ # the first value.
414
+ #
415
+ # @return [DataFrame]
416
+ #
417
+ # @example
418
+ # series_num = Polars::Series.new([1, 2, 3, 4, 5])
419
+ # series_num.describe
420
+ # # =>
421
+ # # shape: (6, 2)
422
+ # # ┌────────────┬──────────┐
423
+ # # │ statistic ┆ value │
424
+ # # │ --- ┆ --- │
425
+ # # │ str ┆ f64 │
426
+ # # ╞════════════╪══════════╡
427
+ # # │ min ┆ 1.0 │
428
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
429
+ # # │ max ┆ 5.0 │
430
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
431
+ # # │ null_count ┆ 0.0 │
432
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
433
+ # # │ mean ┆ 3.0 │
434
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
435
+ # # │ std ┆ 1.581139 │
436
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
437
+ # # │ count ┆ 5.0 │
438
+ # # └────────────┴──────────┘
439
+ #
440
+ # @example
441
+ # series_str = Polars::Series.new(["a", "a", nil, "b", "c"])
442
+ # series_str.describe
443
+ # # =>
444
+ # # shape: (3, 2)
445
+ # # ┌────────────┬───────┐
446
+ # # │ statistic ┆ value │
447
+ # # │ --- ┆ --- │
448
+ # # │ str ┆ i64 │
449
+ # # ╞════════════╪═══════╡
450
+ # # │ unique ┆ 4 │
451
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
452
+ # # │ null_count ┆ 1 │
453
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
454
+ # # │ count ┆ 5 │
455
+ # # └────────────┴───────┘
456
+ def describe
457
+ if len == 0
458
+ raise ArgumentError, "Series must contain at least one value"
459
+ elsif is_numeric
460
+ s = cast(:f64)
461
+ stats = {
462
+ "min" => s.min,
463
+ "max" => s.max,
464
+ "null_count" => s.null_count,
465
+ "mean" => s.mean,
466
+ "std" => s.std,
467
+ "count" => s.len
468
+ }
469
+ elsif is_boolean
470
+ stats = {
471
+ "sum" => sum,
472
+ "null_count" => null_count,
473
+ "count" => len
474
+ }
475
+ elsif is_utf8
476
+ stats = {
477
+ "unique" => unique.length,
478
+ "null_count" => null_count,
479
+ "count" => len
480
+ }
481
+ elsif is_datelike
482
+ # we coerce all to string, because a polars column
483
+ # only has a single dtype and dates: datetime and count: int don't match
484
+ stats = {
485
+ "min" => dt.min.to_s,
486
+ "max" => dt.max.to_s,
487
+ "null_count" => null_count.to_s,
488
+ "count" => len.to_s
489
+ }
490
+ else
491
+ raise TypeError, "This type is not supported"
492
+ end
493
+
494
+ Polars::DataFrame.new(
495
+ {"statistic" => stats.keys, "value" => stats.values}
496
+ )
497
+ end
498
+
499
+ # Reduce this Series to the sum value.
500
+ #
501
+ # @return [Numeric]
502
+ #
503
+ # @note
504
+ # Dtypes `:i8`, `:u8`, `:i16`, and `:u16` are cast to
505
+ # `:i64` before summing to prevent overflow issues.
506
+ #
507
+ # @example
508
+ # s = Polars::Series.new("a", [1, 2, 3])
509
+ # s.sum
510
+ # # => 6
511
+ def sum
512
+ _s.sum
513
+ end
514
+
515
+ # Reduce this Series to the mean value.
516
+ #
517
+ # @return [Float, nil]
518
+ #
519
+ # @example
520
+ # s = Polars::Series.new("a", [1, 2, 3])
521
+ # s.mean
522
+ # # => 2.0
523
+ def mean
524
+ _s.mean
525
+ end
526
+
527
+ # Reduce this Series to the product value.
528
+ #
529
+ # @return [Numeric]
530
+ def product
531
+ to_frame.select(Polars.col(name).product).to_series[0]
532
+ end
533
+
534
+ # Get the minimal value in this Series.
535
+ #
536
+ # @return [Object]
537
+ #
538
+ # @example
539
+ # s = Polars::Series.new("a", [1, 2, 3])
540
+ # s.min
541
+ # # => 1
542
+ def min
543
+ _s.min
544
+ end
545
+
546
+ # Get the maximum value in this Series.
547
+ #
548
+ # @return [Object]
549
+ #
550
+ # @example
551
+ # s = Polars::Series.new("a", [1, 2, 3])
552
+ # s.max
553
+ # # => 3
554
+ def max
555
+ _s.max
556
+ end
557
+
558
+ # Get maximum value, but propagate/poison encountered NaN values.
559
+ #
560
+ # @return [Object]
561
+ def nan_max
562
+ to_frame.select(Polars.col(name).nan_max)[0, 0]
563
+ end
564
+
565
+ # Get minimum value, but propagate/poison encountered NaN values.
566
+ #
567
+ # @return [Object]
568
+ def nan_min
569
+ to_frame.select(Polars.col(name).nan_min)[0, 0]
570
+ end
571
+
572
+ # Get the standard deviation of this Series.
573
+ #
574
+ # @param ddof [Integer]
575
+ # “Delta Degrees of Freedom”: the divisor used in the calculation is N - ddof,
576
+ # where N represents the number of elements.
577
+ #
578
+ # @return [Float, nil]
579
+ #
580
+ # @example
581
+ # s = Polars::Series.new("a", [1, 2, 3])
582
+ # s.std
583
+ # # => 1.0
584
+ def std(ddof: 1)
585
+ if !is_numeric
586
+ nil
587
+ else
588
+ to_frame.select(Polars.col(name).std(ddof: ddof)).to_series[0]
589
+ end
590
+ end
591
+
592
+ # Get variance of this Series.
593
+ #
594
+ # @param ddof [Integer]
595
+ # “Delta Degrees of Freedom”: the divisor used in the calculation is N - ddof,
596
+ # where N represents the number of elements.
597
+ #
598
+ # @return [Float, nil]
599
+ #
600
+ # @example
601
+ # s = Polars::Series.new("a", [1, 2, 3])
602
+ # s.var
603
+ # # => 1.0
604
+ def var(ddof: 1)
605
+ if !is_numeric
606
+ nil
607
+ else
608
+ to_frame.select(Polars.col(name).var(ddof: ddof)).to_series[0]
609
+ end
610
+ end
611
+
612
+ # Get the median of this Series.
613
+ #
614
+ # @return [Float, nil]
615
+ #
616
+ # @example
617
+ # s = Polars::Series.new("a", [1, 2, 3])
618
+ # s.median
619
+ # # => 2.0
620
+ def median
621
+ _s.median
622
+ end
623
+
624
+ # Get the quantile value of this Series.
625
+ #
626
+ # @param quantile [Float, nil]
627
+ # Quantile between 0.0 and 1.0.
628
+ # @param interpolation ["nearest", "higher", "lower", "midpoint", "linear"]
629
+ # Interpolation method.
630
+ #
631
+ # @return [Float, nil]
632
+ #
633
+ # @example
634
+ # s = Polars::Series.new("a", [1, 2, 3])
635
+ # s.quantile(0.5)
636
+ # # => 2.0
637
+ def quantile(quantile, interpolation: "nearest")
638
+ _s.quantile(quantile, interpolation)
639
+ end
640
+
641
+ # Get dummy variables.
642
+ #
643
+ # @return [DataFrame]
644
+ #
645
+ # @example
646
+ # s = Polars::Series.new("a", [1, 2, 3])
647
+ # s.to_dummies
648
+ # # =>
649
+ # # shape: (3, 3)
650
+ # # ┌─────┬─────┬─────┐
651
+ # # │ a_1 ┆ a_2 ┆ a_3 │
652
+ # # │ --- ┆ --- ┆ --- │
653
+ # # │ u8 ┆ u8 ┆ u8 │
654
+ # # ╞═════╪═════╪═════╡
655
+ # # │ 1 ┆ 0 ┆ 0 │
656
+ # # ├╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┤
657
+ # # │ 0 ┆ 1 ┆ 0 │
658
+ # # ├╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┤
659
+ # # │ 0 ┆ 0 ┆ 1 │
660
+ # # └─────┴─────┴─────┘
661
+ def to_dummies
662
+ Utils.wrap_df(_s.to_dummies)
663
+ end
664
+
665
+ # Count the unique values in a Series.
666
+ #
667
+ # @param sort [Boolean]
668
+ # Ensure the output is sorted from most values to least.
669
+ #
670
+ # @return [DataFrame]
671
+ #
672
+ # @example
673
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
674
+ # s.value_counts.sort("a")
675
+ # # =>
676
+ # # shape: (3, 2)
677
+ # # ┌─────┬────────┐
678
+ # # │ a ┆ counts │
679
+ # # │ --- ┆ --- │
680
+ # # │ i64 ┆ u32 │
681
+ # # ╞═════╪════════╡
682
+ # # │ 1 ┆ 1 │
683
+ # # ├╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
684
+ # # │ 2 ┆ 2 │
685
+ # # ├╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
686
+ # # │ 3 ┆ 1 │
687
+ # # └─────┴────────┘
688
+ def value_counts(sort: false)
689
+ Utils.wrap_df(_s.value_counts(sort))
690
+ end
691
+
692
+ # Return a count of the unique values in the order of appearance.
693
+ #
694
+ # @return [Series]
695
+ #
696
+ # @example
697
+ # s = Polars::Series.new("id", ["a", "b", "b", "c", "c", "c"])
698
+ # s.unique_counts
699
+ # # =>
700
+ # # shape: (3,)
701
+ # # Series: 'id' [u32]
702
+ # # [
703
+ # # 1
704
+ # # 2
705
+ # # 3
706
+ # # ]
707
+ def unique_counts
708
+ super
709
+ end
710
+
711
+ # Computes the entropy.
712
+ #
713
+ # Uses the formula `-sum(pk * log(pk)` where `pk` are discrete probabilities.
714
+ #
715
+ # @param base [Float]
716
+ # Given base, defaults to `e`
717
+ # @param normalize [Boolean]
718
+ # Normalize pk if it doesn't sum to 1.
719
+ #
720
+ # @return [Float, nil]
721
+ #
722
+ # @example
723
+ # a = Polars::Series.new([0.99, 0.005, 0.005])
724
+ # a.entropy(normalize: true)
725
+ # # => 0.06293300616044681
726
+ #
727
+ # @example
728
+ # b = Polars::Series.new([0.65, 0.10, 0.25])
729
+ # b.entropy(normalize: true)
730
+ # # => 0.8568409950394724
731
+ def entropy(base: Math::E, normalize: false)
732
+ Polars.select(Polars.lit(self).entropy(base: base, normalize: normalize)).to_series[0]
733
+ end
734
+
735
+ # Run an expression over a sliding window that increases `1` slot every iteration.
736
+ #
737
+ # @param expr [Expr]
738
+ # Expression to evaluate
739
+ # @param min_periods [Integer]
740
+ # Number of valid values there should be in the window before the expression
741
+ # is evaluated. valid values = `length - null_count`
742
+ # @param parallel [Boolean]
743
+ # Run in parallel. Don't do this in a groupby or another operation that
744
+ # already has much parallelization.
745
+ #
746
+ # @return [Series]
747
+ #
748
+ # @note
749
+ # This functionality is experimental and may change without it being considered a
750
+ # breaking change.
751
+ #
752
+ # @note
753
+ # This can be really slow as it can have `O(n^2)` complexity. Don't use this
754
+ # for operations that visit all elements.
755
+ #
756
+ # @example
757
+ # s = Polars::Series.new("values", [1, 2, 3, 4, 5])
758
+ # s.cumulative_eval(Polars.element.first - Polars.element.last ** 2)
759
+ # # =>
760
+ # # shape: (5,)
761
+ # # Series: 'values' [f64]
762
+ # # [
763
+ # # 0.0
764
+ # # -3.0
765
+ # # -8.0
766
+ # # -15.0
767
+ # # -24.0
768
+ # # ]
769
+ def cumulative_eval(expr, min_periods: 1, parallel: false)
770
+ super
771
+ end
772
+
773
+ # Return a copy of the Series with a new alias/name.
774
+ #
775
+ # @param name [String]
776
+ # New name.
777
+ #
778
+ # @return [Series]
779
+ #
780
+ # @example
781
+ # s = Polars::Series.new("x", [1, 2, 3])
782
+ # s.alias("y")
783
+ def alias(name)
784
+ s = dup
785
+ s._s.rename(name)
786
+ s
787
+ end
788
+
789
+ # Rename this Series.
790
+ #
791
+ # @param name [String]
792
+ # New name.
793
+ # @param in_place [Boolean]
794
+ # Modify the Series in-place.
795
+ #
796
+ # @return [Series]
797
+ #
798
+ # @example
799
+ # s = Polars::Series.new("a", [1, 2, 3])
800
+ # s.rename("b")
801
+ def rename(name, in_place: false)
802
+ if in_place
803
+ _s.rename(name)
804
+ self
805
+ else
806
+ self.alias(name)
807
+ end
808
+ end
809
+
810
+ # Get the length of each individual chunk.
811
+ #
812
+ # @return [Array]
813
+ #
814
+ # @example
815
+ # s = Polars::Series.new("a", [1, 2, 3])
816
+ # s2 = Polars::Series.new("b", [4, 5, 6])
817
+ #
818
+ # @example Concatenate Series with rechunk: true
819
+ # Polars.concat([s, s2]).chunk_lengths
820
+ # # => [6]
821
+ #
822
+ # @example Concatenate Series with rechunk: false
823
+ # Polars.concat([s, s2], rechunk: false).chunk_lengths
824
+ # # => [3, 3]
825
+ def chunk_lengths
826
+ _s.chunk_lengths
827
+ end
828
+
829
+ # Get the number of chunks that this Series contains.
830
+ #
831
+ # @return [Integer]
832
+ #
833
+ # @example
834
+ # s = Polars::Series.new("a", [1, 2, 3])
835
+ # s2 = Polars::Series.new("b", [4, 5, 6])
836
+ #
837
+ # @example Concatenate Series with rechunk: true
838
+ # Polars.concat([s, s2]).n_chunks
839
+ # # => 1
840
+ #
841
+ # @example Concatenate Series with rechunk: false
842
+ # Polars.concat([s, s2], rechunk: false).n_chunks
843
+ # # => 2
844
+ def n_chunks
845
+ _s.n_chunks
846
+ end
847
+
848
+ # Get an array with the cumulative sum computed at every element.
849
+ #
850
+ # @param reverse [Boolean]
851
+ # reverse the operation.
852
+ #
853
+ # @return [Series]
854
+ #
855
+ # @note
856
+ # Dtypes `:i8`, `:u8`, `:i16`, and `:u16` are cast to
857
+ # `:i64` before summing to prevent overflow issues.
858
+ #
859
+ # @example
860
+ # s = Polars::Series.new("a", [1, 2, 3])
861
+ # s.cumsum
862
+ # # =>
863
+ # # shape: (3,)
864
+ # # Series: 'a' [i64]
865
+ # # [
866
+ # # 1
867
+ # # 3
868
+ # # 6
869
+ # # ]
870
+ def cumsum(reverse: false)
871
+ super
872
+ end
873
+
874
+ # Get an array with the cumulative min computed at every element.
875
+ #
876
+ # @param reverse [Boolean]
877
+ # reverse the operation.
878
+ #
879
+ # @return [Series]
880
+ #
881
+ # @example
882
+ # s = Polars::Series.new("a", [3, 5, 1])
883
+ # s.cummin
884
+ # # =>
885
+ # # shape: (3,)
886
+ # # Series: 'a' [i64]
887
+ # # [
888
+ # # 3
889
+ # # 3
890
+ # # 1
891
+ # # ]
892
+ def cummin(reverse: false)
893
+ super
894
+ end
895
+
896
+ # Get an array with the cumulative max computed at every element.
897
+ #
898
+ # @param reverse [Boolean]
899
+ # reverse the operation.
900
+ #
901
+ # @return [Series]
902
+ #
903
+ # @example
904
+ # s = Polars::Series.new("a", [3, 5, 1])
905
+ # s.cummax
906
+ # # =>
907
+ # # shape: (3,)
908
+ # # Series: 'a' [i64]
909
+ # # [
910
+ # # 3
911
+ # # 5
912
+ # # 5
913
+ # # ]
914
+ def cummax(reverse: false)
915
+ super
916
+ end
917
+
918
+ # Get an array with the cumulative product computed at every element.
919
+ #
920
+ # @param reverse [Boolean]
921
+ # reverse the operation.
922
+ #
923
+ # @return [Series]
924
+ #
925
+ # @note
926
+ # Dtypes `:i8`, `:u8`, `:i16`, and `:u16` are cast to
927
+ # `:i64` before multiplying to prevent overflow issues.
928
+ #
929
+ # @example
930
+ # s = Polars::Series.new("a", [1, 2, 3])
931
+ # s.cumprod
932
+ # # =>
933
+ # # shape: (3,)
934
+ # # Series: 'a' [i64]
935
+ # # [
936
+ # # 1
937
+ # # 2
938
+ # # 6
939
+ # # ]
940
+ def cumprod(reverse: false)
941
+ super
942
+ end
943
+
944
+ # Get the first `n` rows.
945
+ #
946
+ # Alias for {#head}.
947
+ #
948
+ # @param n [Integer]
949
+ # Number of rows to return.
950
+ #
951
+ # @return [Series]
952
+ #
953
+ # @example
954
+ # s = Polars::Series.new("a", [1, 2, 3])
955
+ # s.limit(2)
956
+ # # =>
957
+ # # shape: (2,)
958
+ # # Series: 'a' [i64]
959
+ # # [
960
+ # # 1
961
+ # # 2
962
+ # # ]
963
+ def limit(n = 10)
964
+ to_frame.select(Utils.col(name).limit(n)).to_series
965
+ end
966
+
967
+ # Get a slice of this Series.
968
+ #
969
+ # @param offset [Integer]
970
+ # Start index. Negative indexing is supported.
971
+ # @param length [Integer, nil]
972
+ # Length of the slice. If set to `nil`, all rows starting at the offset
973
+ # will be selected.
974
+ #
975
+ # @return [Series]
976
+ #
977
+ # @example
978
+ # s = Polars::Series.new("a", [1, 2, 3, 4])
979
+ # s.slice(1, 2)
980
+ # # =>
981
+ # # shape: (2,)
982
+ # # Series: 'a' [i64]
983
+ # # [
984
+ # # 2
985
+ # # 3
986
+ # # ]
987
+ def slice(offset, length = nil)
988
+ super
989
+ end
990
+
991
+ # Append a Series to this one.
992
+ #
993
+ # @param other [Series]
994
+ # Series to append.
995
+ # @param append_chunks [Boolean]
996
+ # If set to `true` the append operation will add the chunks from `other` to
997
+ # self. This is super cheap.
998
+ #
999
+ # If set to `false` the append operation will do the same as
1000
+ # {DataFrame#extend} which extends the memory backed by this Series with
1001
+ # the values from `other`.
1002
+ #
1003
+ # Different from `append_chunks`, `extend` appends the data from `other` to
1004
+ # the underlying memory locations and thus may cause a reallocation (which is
1005
+ # expensive).
1006
+ #
1007
+ # If this does not cause a reallocation, the resulting data structure will not
1008
+ # have any extra chunks and thus will yield faster queries.
1009
+ #
1010
+ # Prefer `extend` over `append_chunks` when you want to do a query after a
1011
+ # single append. For instance during online operations where you add `n` rows
1012
+ # and rerun a query.
1013
+ #
1014
+ # Prefer `append_chunks` over `extend` when you want to append many times
1015
+ # before doing a query. For instance, when you read in multiple files and when
1016
+ # to store them in a single Series. In the latter case, finish the sequence
1017
+ # of `append_chunks` operations with a `rechunk`.
1018
+ #
1019
+ # @return [Series]
1020
+ #
1021
+ # @example
1022
+ # s = Polars::Series.new("a", [1, 2, 3])
1023
+ # s2 = Polars::Series.new("b", [4, 5, 6])
1024
+ # s.append(s2)
1025
+ # # =>
1026
+ # # shape: (6,)
1027
+ # # Series: 'a' [i64]
1028
+ # # [
1029
+ # # 1
1030
+ # # 2
1031
+ # # 3
1032
+ # # 4
1033
+ # # 5
1034
+ # # 6
1035
+ # # ]
1036
+ def append(other, append_chunks: true)
1037
+ begin
1038
+ if append_chunks
1039
+ _s.append(other._s)
1040
+ else
1041
+ _s.extend(other._s)
1042
+ end
1043
+ rescue => e
1044
+ if e.message == "Already mutably borrowed"
1045
+ append(other.clone, append_chunks)
1046
+ else
1047
+ raise e
1048
+ end
1049
+ end
1050
+ self
1051
+ end
1052
+
1053
+ # Filter elements by a boolean mask.
1054
+ #
1055
+ # @param predicate [Series, Array]
1056
+ # Boolean mask.
1057
+ #
1058
+ # @return [Series]
1059
+ #
1060
+ # @example
1061
+ # s = Polars::Series.new("a", [1, 2, 3])
1062
+ # mask = Polars::Series.new("", [true, false, true])
1063
+ # s.filter(mask)
1064
+ # # =>
1065
+ # # shape: (2,)
1066
+ # # Series: 'a' [i64]
1067
+ # # [
1068
+ # # 1
1069
+ # # 3
1070
+ # # ]
1071
+ def filter(predicate)
1072
+ if predicate.is_a?(Array)
1073
+ predicate = Series.new("", predicate)
1074
+ end
1075
+ Utils.wrap_s(_s.filter(predicate._s))
1076
+ end
1077
+
1078
+ # Get the first `n` rows.
1079
+ #
1080
+ # @param n [Integer]
1081
+ # Number of rows to return.
1082
+ #
1083
+ # @return [Series]
1084
+ #
1085
+ # @example
1086
+ # s = Polars::Series.new("a", [1, 2, 3])
1087
+ # s.head(2)
1088
+ # # =>
1089
+ # # shape: (2,)
1090
+ # # Series: 'a' [i64]
1091
+ # # [
1092
+ # # 1
1093
+ # # 2
1094
+ # # ]
1095
+ def head(n = 10)
1096
+ to_frame.select(Utils.col(name).head(n)).to_series
1097
+ end
1098
+
1099
+ # Get the last `n` rows.
1100
+ #
1101
+ # @param n [Integer]
1102
+ # Number of rows to return.
1103
+ #
1104
+ # @return [Series]
1105
+ #
1106
+ # @example
1107
+ # s = Polars::Series.new("a", [1, 2, 3])
1108
+ # s.tail(2)
1109
+ # # =>
1110
+ # # shape: (2,)
1111
+ # # Series: 'a' [i64]
1112
+ # # [
1113
+ # # 2
1114
+ # # 3
1115
+ # # ]
1116
+ def tail(n = 10)
1117
+ to_frame.select(Utils.col(name).tail(n)).to_series
1118
+ end
1119
+
1120
+ # Take every nth value in the Series and return as new Series.
1121
+ #
1122
+ # @return [Series]
1123
+ #
1124
+ # @example
1125
+ # s = Polars::Series.new("a", [1, 2, 3, 4])
1126
+ # s.take_every(2)
1127
+ # # =>
1128
+ # # shape: (2,)
1129
+ # # Series: 'a' [i64]
1130
+ # # [
1131
+ # # 1
1132
+ # # 3
1133
+ # # ]
1134
+ def take_every(n)
1135
+ super
1136
+ end
1137
+
1138
+ # Sort this Series.
1139
+ #
1140
+ # @param reverse [Boolean]
1141
+ # Reverse sort.
1142
+ # @param in_place [Boolean]
1143
+ # Sort in place.
1144
+ #
1145
+ # @return [Series]
1146
+ #
1147
+ # @example
1148
+ # s = Polars::Series.new("a", [1, 3, 4, 2])
1149
+ # s.sort
1150
+ # # =>
1151
+ # # shape: (4,)
1152
+ # # Series: 'a' [i64]
1153
+ # # [
1154
+ # # 1
1155
+ # # 2
1156
+ # # 3
1157
+ # # 4
1158
+ # # ]
1159
+ # s.sort(reverse: true)
1160
+ # # =>
1161
+ # # shape: (4,)
1162
+ # # Series: 'a' [i64]
1163
+ # # [
1164
+ # # 4
1165
+ # # 3
1166
+ # # 2
1167
+ # # 1
1168
+ # # ]
1169
+ def sort(reverse: false, in_place: false)
1170
+ if in_place
1171
+ self._s = _s.sort(reverse)
1172
+ self
1173
+ else
1174
+ Utils.wrap_s(_s.sort(reverse))
1175
+ end
1176
+ end
1177
+
1178
+ # Return the `k` largest elements.
1179
+ #
1180
+ # If `reverse: true`, the smallest elements will be given.
1181
+ #
1182
+ # @param k [Integer]
1183
+ # Number of elements to return.
1184
+ # @param reverse [Boolean]
1185
+ # Return the smallest elements.
1186
+ #
1187
+ # @return [Boolean]
1188
+ def top_k(k: 5, reverse: false)
1189
+ super
1190
+ end
1191
+
1192
+ # Get the index values that would sort this Series.
1193
+ #
1194
+ # @param reverse [Boolean]
1195
+ # Sort in reverse (descending) order.
1196
+ # @param nulls_last [Boolean]
1197
+ # Place null values last instead of first.
1198
+ #
1199
+ # @return [Series]
1200
+ #
1201
+ # @example
1202
+ # s = Polars::Series.new("a", [5, 3, 4, 1, 2])
1203
+ # s.arg_sort
1204
+ # # =>
1205
+ # # shape: (5,)
1206
+ # # Series: 'a' [u32]
1207
+ # # [
1208
+ # # 3
1209
+ # # 4
1210
+ # # 1
1211
+ # # 2
1212
+ # # 0
1213
+ # # ]
1214
+ def arg_sort(reverse: false, nulls_last: false)
1215
+ super
1216
+ end
1217
+
1218
+ # Get the index values that would sort this Series.
1219
+ #
1220
+ # Alias for {#arg_sort}.
1221
+ #
1222
+ # @param reverse [Boolean]
1223
+ # Sort in reverse (descending) order.
1224
+ # @param nulls_last [Boolean]
1225
+ # Place null values last instead of first.
1226
+ #
1227
+ # @return [Series]
1228
+ def argsort(reverse: false, nulls_last: false)
1229
+ super
1230
+ end
1231
+
1232
+ # Get unique index as Series.
1233
+ #
1234
+ # @return [Series]
1235
+ #
1236
+ # @example
1237
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1238
+ # s.arg_unique
1239
+ # # =>
1240
+ # # shape: (3,)
1241
+ # # Series: 'a' [u32]
1242
+ # # [
1243
+ # # 0
1244
+ # # 1
1245
+ # # 3
1246
+ # # ]
1247
+ def arg_unique
1248
+ super
1249
+ end
1250
+
1251
+ # Get the index of the minimal value.
1252
+ #
1253
+ # @return [Integer, nil]
1254
+ #
1255
+ # @example
1256
+ # s = Polars::Series.new("a", [3, 2, 1])
1257
+ # s.arg_min
1258
+ # # => 2
1259
+ def arg_min
1260
+ _s.arg_min
1261
+ end
1262
+
1263
+ # Get the index of the maximal value.
1264
+ #
1265
+ # @return [Integer, nil]
1266
+ #
1267
+ # @example
1268
+ # s = Polars::Series.new("a", [3, 2, 1])
1269
+ # s.arg_max
1270
+ # # => 0
1271
+ def arg_max
1272
+ _s.arg_max
1273
+ end
1274
+
1275
+ # Find indices where elements should be inserted to maintain order.
1276
+ #
1277
+ # @param element [Object]
1278
+ # Expression or scalar value.
1279
+ #
1280
+ # @return [Integer]
1281
+ def search_sorted(element)
1282
+ Polars.select(Polars.lit(self).search_sorted(element))[0, 0]
1283
+ end
1284
+
1285
+ # Get unique elements in series.
1286
+ #
1287
+ # @param maintain_order [Boolean]
1288
+ # Maintain order of data. This requires more work.
1289
+ #
1290
+ # @return [Series]
1291
+ #
1292
+ # @example
1293
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1294
+ # s.unique.sort
1295
+ # # =>
1296
+ # # shape: (3,)
1297
+ # # Series: 'a' [i64]
1298
+ # # [
1299
+ # # 1
1300
+ # # 2
1301
+ # # 3
1302
+ # # ]
1303
+ def unique(maintain_order: false)
1304
+ super
1305
+ end
1306
+
1307
+ # Take values by index.
1308
+ #
1309
+ # @param indices [Array]
1310
+ # Index location used for selection.
1311
+ #
1312
+ # @return [Series]
1313
+ #
1314
+ # @example
1315
+ # s = Polars::Series.new("a", [1, 2, 3, 4])
1316
+ # s.take([1, 3])
1317
+ # # =>
1318
+ # # shape: (2,)
1319
+ # # Series: 'a' [i64]
1320
+ # # [
1321
+ # # 2
1322
+ # # 4
1323
+ # # ]
1324
+ def take(indices)
1325
+ to_frame.select(Polars.col(name).take(indices)).to_series
1326
+ end
1327
+
1328
+ # Count the null values in this Series.
1329
+ #
1330
+ # @return [Integer]
1331
+ def null_count
1332
+ _s.null_count
1333
+ end
1334
+
1335
+ # Return `true` if the Series has a validity bitmask.
1336
+ #
1337
+ # If there is none, it means that there are no null values.
1338
+ # Use this to swiftly assert a Series does not have null values.
1339
+ #
1340
+ # @return [Boolean]
1341
+ def has_validity
1342
+ _s.has_validity
1343
+ end
1344
+
1345
+ # Check if the Series is empty.
1346
+ #
1347
+ # @return [Boolean]
1348
+ #
1349
+ # @example
1350
+ # s = Polars::Series.new("a", [])
1351
+ # s.is_empty
1352
+ # # => true
1353
+ def is_empty
1354
+ len == 0
1355
+ end
1356
+ alias_method :empty?, :is_empty
1357
+
1358
+ # Returns a boolean Series indicating which values are null.
1359
+ #
1360
+ # @return [Series]
1361
+ #
1362
+ # @example
1363
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, nil])
1364
+ # s.is_null
1365
+ # # =>
1366
+ # # shape: (4,)
1367
+ # # Series: 'a' [bool]
1368
+ # # [
1369
+ # # false
1370
+ # # false
1371
+ # # false
1372
+ # # true
1373
+ # # ]
1374
+ def is_null
1375
+ super
1376
+ end
1377
+
1378
+ # Returns a boolean Series indicating which values are not null.
1379
+ #
1380
+ # @return [Series]
1381
+ #
1382
+ # @example
1383
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, nil])
1384
+ # s.is_not_null
1385
+ # # =>
1386
+ # # shape: (4,)
1387
+ # # Series: 'a' [bool]
1388
+ # # [
1389
+ # # true
1390
+ # # true
1391
+ # # true
1392
+ # # false
1393
+ # # ]
1394
+ def is_not_null
1395
+ super
1396
+ end
1397
+
1398
+ # Returns a boolean Series indicating which values are finite.
1399
+ #
1400
+ # @return [Series]
1401
+ #
1402
+ # @example
1403
+ # s = Polars::Series.new("a", [1.0, 2.0, Float::INFINITY])
1404
+ # s.is_finite
1405
+ # # =>
1406
+ # # shape: (3,)
1407
+ # # Series: 'a' [bool]
1408
+ # # [
1409
+ # # true
1410
+ # # true
1411
+ # # false
1412
+ # # ]
1413
+ def is_finite
1414
+ super
1415
+ end
1416
+
1417
+ # Returns a boolean Series indicating which values are infinite.
1418
+ #
1419
+ # @return [Series]
1420
+ #
1421
+ # @example
1422
+ # s = Polars::Series.new("a", [1.0, 2.0, Float::INFINITY])
1423
+ # s.is_infinite
1424
+ # # =>
1425
+ # # shape: (3,)
1426
+ # # Series: 'a' [bool]
1427
+ # # [
1428
+ # # false
1429
+ # # false
1430
+ # # true
1431
+ # # ]
1432
+ def is_infinite
1433
+ super
1434
+ end
1435
+
1436
+ # Returns a boolean Series indicating which values are NaN.
1437
+ #
1438
+ # @return [Series]
1439
+ #
1440
+ # @example
1441
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, Float::NAN])
1442
+ # s.is_nan
1443
+ # # =>
1444
+ # # shape: (4,)
1445
+ # # Series: 'a' [bool]
1446
+ # # [
1447
+ # # false
1448
+ # # false
1449
+ # # false
1450
+ # # true
1451
+ # # ]
1452
+ def is_nan
1453
+ super
1454
+ end
1455
+
1456
+ # Returns a boolean Series indicating which values are not NaN.
1457
+ #
1458
+ # @return [Series]
1459
+ #
1460
+ # @example
1461
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, Float::NAN])
1462
+ # s.is_not_nan
1463
+ # # =>
1464
+ # # shape: (4,)
1465
+ # # Series: 'a' [bool]
1466
+ # # [
1467
+ # # true
1468
+ # # true
1469
+ # # true
1470
+ # # false
1471
+ # # ]
1472
+ def is_not_nan
1473
+ super
1474
+ end
1475
+
1476
+ # Check if elements of this Series are in the other Series.
1477
+ #
1478
+ # @return [Series]
1479
+ #
1480
+ # @example
1481
+ # s = Polars::Series.new("a", [1, 2, 3])
1482
+ # s2 = Polars::Series.new("b", [2, 4])
1483
+ # s2.is_in(s)
1484
+ # # =>
1485
+ # # shape: (2,)
1486
+ # # Series: 'b' [bool]
1487
+ # # [
1488
+ # # true
1489
+ # # false
1490
+ # # ]
1491
+ #
1492
+ # @example
1493
+ # sets = Polars::Series.new("sets", [[1, 2, 3], [1, 2], [9, 10]])
1494
+ # # =>
1495
+ # # shape: (3,)
1496
+ # # Series: 'sets' [list]
1497
+ # # [
1498
+ # # [1, 2, 3]
1499
+ # # [1, 2]
1500
+ # # [9, 10]
1501
+ # # ]
1502
+ #
1503
+ # @example
1504
+ # optional_members = Polars::Series.new("optional_members", [1, 2, 3])
1505
+ # # =>
1506
+ # # shape: (3,)
1507
+ # # Series: 'optional_members' [i64]
1508
+ # # [
1509
+ # # 1
1510
+ # # 2
1511
+ # # 3
1512
+ # # ]
1513
+ #
1514
+ # @example
1515
+ # optional_members.is_in(sets)
1516
+ # # =>
1517
+ # # shape: (3,)
1518
+ # # Series: 'optional_members' [bool]
1519
+ # # [
1520
+ # # true
1521
+ # # true
1522
+ # # false
1523
+ # # ]
1524
+ def is_in(other)
1525
+ super
1526
+ end
1527
+
1528
+ # Get index values where Boolean Series evaluate `true`.
1529
+ #
1530
+ # @return [Series]
1531
+ #
1532
+ # @example
1533
+ # s = Polars::Series.new("a", [1, 2, 3])
1534
+ # (s == 2).arg_true
1535
+ # # =>
1536
+ # # shape: (1,)
1537
+ # # Series: 'a' [u32]
1538
+ # # [
1539
+ # # 1
1540
+ # # ]
1541
+ def arg_true
1542
+ Polars.arg_where(self, eager: true)
1543
+ end
1544
+
1545
+ # Get mask of all unique values.
1546
+ #
1547
+ # @return [Series]
1548
+ #
1549
+ # @example
1550
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1551
+ # s.is_unique
1552
+ # # =>
1553
+ # # shape: (4,)
1554
+ # # Series: 'a' [bool]
1555
+ # # [
1556
+ # # true
1557
+ # # false
1558
+ # # false
1559
+ # # true
1560
+ # # ]
1561
+ def is_unique
1562
+ super
1563
+ end
1564
+
1565
+ # Get a mask of the first unique value.
1566
+ #
1567
+ # @return [Series]
1568
+ def is_first
1569
+ super
1570
+ end
1571
+
1572
+ # Get mask of all duplicated values.
1573
+ #
1574
+ # @return [Series]
1575
+ #
1576
+ # @example
1577
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1578
+ # s.is_duplicated
1579
+ # # =>
1580
+ # # shape: (4,)
1581
+ # # Series: 'a' [bool]
1582
+ # # [
1583
+ # # false
1584
+ # # true
1585
+ # # true
1586
+ # # false
1587
+ # # ]
1588
+ def is_duplicated
1589
+ super
1590
+ end
1591
+
1592
+ # Explode a list or utf8 Series.
1593
+ #
1594
+ # This means that every item is expanded to a new row.
1595
+ #
1596
+ # @return [Series]
1597
+ #
1598
+ # @example
1599
+ # s = Polars::Series.new("a", [[1, 2], [3, 4], [9, 10]])
1600
+ # s.explode
1601
+ # # =>
1602
+ # # shape: (6,)
1603
+ # # Series: 'a' [i64]
1604
+ # # [
1605
+ # # 1
1606
+ # # 2
1607
+ # # 3
1608
+ # # 4
1609
+ # # 9
1610
+ # # 10
1611
+ # # ]
1612
+ def explode
1613
+ super
1614
+ end
1615
+
1616
+ # Check if series is equal with another Series.
1617
+ #
1618
+ # @param other [Series]
1619
+ # Series to compare with.
1620
+ # @param null_equal [Boolean]
1621
+ # Consider null values as equal.
1622
+ # @param strict [Boolean]
1623
+ # Don't allow different numerical dtypes, e.g. comparing `:u32` with a
1624
+ # `:i64` will return `false`.
1625
+ #
1626
+ # @return [Boolean]
1627
+ #
1628
+ # @example
1629
+ # s = Polars::Series.new("a", [1, 2, 3])
1630
+ # s2 = Polars::Series.new("b", [4, 5, 6])
1631
+ # s.series_equal(s)
1632
+ # # => true
1633
+ # s.series_equal(s2)
1634
+ # # => false
1635
+ def series_equal(other, null_equal: false, strict: false)
1636
+ _s.series_equal(other._s, null_equal, strict)
1637
+ end
1638
+
1639
+ # Length of this Series.
1640
+ #
1641
+ # @return [Integer]
1642
+ #
1643
+ # @example
1644
+ # s = Polars::Series.new("a", [1, 2, 3])
1645
+ # s.len
1646
+ # # => 3
1647
+ def len
1648
+ _s.len
1649
+ end
1650
+ alias_method :length, :len
1651
+
1652
+ # Cast between data types.
1653
+ #
1654
+ # @param dtype [Symbol]
1655
+ # DataType to cast to
1656
+ # @param strict [Boolean]
1657
+ # Throw an error if a cast could not be done for instance due to an overflow
1658
+ #
1659
+ # @return [Series]
1660
+ #
1661
+ # @example
1662
+ # s = Polars::Series.new("a", [true, false, true])
1663
+ # s.cast(:u32)
1664
+ # # =>
1665
+ # # shape: (3,)
1666
+ # # Series: 'a' [u32]
1667
+ # # [
1668
+ # # 1
1669
+ # # 0
1670
+ # # 1
1671
+ # # ]
1672
+ def cast(dtype, strict: true)
1673
+ super
1674
+ end
1675
+
1676
+ # Cast to physical representation of the logical dtype.
1677
+ #
1678
+ # - `:date` -> `:i32`
1679
+ # - `:datetime` -> `:i64`
1680
+ # - `:time` -> `:i64`
1681
+ # - `:duration` -> `:i64`
1682
+ # - `:cat` -> `:u32`
1683
+ # - other data types will be left unchanged.
1684
+ #
1685
+ # @return [Series]
1686
+ #
1687
+ # @example
1688
+ # s = Polars::Series.new("values", ["a", nil, "x", "a"])
1689
+ # s.cast(:cat).to_physical
1690
+ # # =>
1691
+ # # shape: (4,)
1692
+ # # Series: 'values' [u32]
1693
+ # # [
1694
+ # # 0
1695
+ # # null
1696
+ # # 1
1697
+ # # 0
1698
+ # # ]
1699
+ def to_physical
1700
+ super
1701
+ end
1702
+
1703
+ # Convert this Series to a Ruby Array. This operation clones data.
1704
+ #
1705
+ # @return [Array]
1706
+ #
1707
+ # @example
1708
+ # s = Polars::Series.new("a", [1, 2, 3])
1709
+ # s.to_a
1710
+ # # => [1, 2, 3]
1711
+ def to_a
1712
+ _s.to_a
1713
+ end
1714
+
1715
+ # Create a single chunk of memory for this Series.
1716
+ #
1717
+ # @param in_place [Boolean]
1718
+ # In place or not.
1719
+ #
1720
+ # @return [Series]
1721
+ def rechunk(in_place: false)
1722
+ opt_s = _s.rechunk(in_place)
1723
+ in_place ? self : Utils.wrap_s(opt_s)
1724
+ end
1725
+
1726
+ # Return Series in reverse order.
1727
+ #
1728
+ # @return [Series]
1729
+ #
1730
+ # @example
1731
+ # s = Polars::Series.new("a", [1, 2, 3], dtype: :i8)
1732
+ # s.reverse
1733
+ # # =>
1734
+ # # shape: (3,)
1735
+ # # Series: 'a' [i8]
1736
+ # # [
1737
+ # # 3
1738
+ # # 2
1739
+ # # 1
1740
+ # # ]
1741
+ def reverse
1742
+ super
1743
+ end
1744
+
1745
+ # Check if this Series datatype is numeric.
1746
+ #
1747
+ # @return [Boolean]
1748
+ #
1749
+ # @example
1750
+ # s = Polars::Series.new("a", [1, 2, 3])
1751
+ # s.is_numeric
1752
+ # # => true
1753
+ def is_numeric
1754
+ [Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64, Float32, Float64].include?(dtype)
1755
+ end
1756
+ alias_method :numeric?, :is_numeric
1757
+
1758
+ # Check if this Series datatype is datelike.
1759
+ #
1760
+ # @return [Boolean]
1761
+ #
1762
+ # @example
1763
+ # s = Polars::Series.new([Date.new(2021, 1, 1), Date.new(2021, 1, 2), Date.new(2021, 1, 3)])
1764
+ # s.is_datelike
1765
+ # # => true
1766
+ def is_datelike
1767
+ [Date, Datetime, Duration, Time].include?(dtype)
1768
+ end
1769
+
1770
+ # Check if this Series has floating point numbers.
1771
+ #
1772
+ # @return [Boolean]
1773
+ #
1774
+ # @example
1775
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0])
1776
+ # s.is_float
1777
+ # # => true
1778
+ def is_float
1779
+ [Float32, Float64].include?(dtype)
1780
+ end
1781
+ alias_method :float?, :is_float
1782
+
1783
+ # Check if this Series is a Boolean.
1784
+ #
1785
+ # @return [Boolean]
1786
+ #
1787
+ # @example
1788
+ # s = Polars::Series.new("a", [true, false, true])
1789
+ # s.is_boolean
1790
+ # # => true
1791
+ def is_boolean
1792
+ dtype == Boolean
1793
+ end
1794
+ alias_method :boolean?, :is_boolean
1795
+ alias_method :is_bool, :is_boolean
1796
+ alias_method :bool?, :is_boolean
1797
+
1798
+ # Check if this Series datatype is a Utf8.
1799
+ #
1800
+ # @return [Boolean]
1801
+ #
1802
+ # @example
1803
+ # s = Polars::Series.new("x", ["a", "b", "c"])
1804
+ # s.is_utf8
1805
+ # # => true
1806
+ def is_utf8
1807
+ dtype == Utf8
1808
+ end
1809
+ alias_method :utf8?, :is_utf8
1810
+
1811
+ # def view
1812
+ # end
1813
+
1814
+ # def to_numo
1815
+ # end
1816
+
1817
+ # Set masked values.
1818
+ #
1819
+ # @param filter [Series]
1820
+ # Boolean mask.
1821
+ # @param value [Object]
1822
+ # Value with which to replace the masked values.
1823
+ #
1824
+ # @return [Series]
1825
+ #
1826
+ # @note
1827
+ # Use of this function is frequently an anti-pattern, as it can
1828
+ # block optimization (predicate pushdown, etc). Consider using
1829
+ # `Polars.when(predicate).then(value).otherwise(self)` instead.
1830
+ #
1831
+ # @example
1832
+ # s = Polars::Series.new("a", [1, 2, 3])
1833
+ # s.set(s == 2, 10)
1834
+ # # =>
1835
+ # # shape: (3,)
1836
+ # # Series: 'a' [i64]
1837
+ # # [
1838
+ # # 1
1839
+ # # 10
1840
+ # # 3
1841
+ # # ]
1842
+ def set(filter, value)
1843
+ Utils.wrap_s(_s.send("set_with_mask_#{DTYPE_TO_FFINAME.fetch(dtype)}", filter._s, value))
1844
+ end
1845
+
1846
+ # Set values at the index locations.
1847
+ #
1848
+ # @param idx [Object]
1849
+ # Integers representing the index locations.
1850
+ # @param value [Object]
1851
+ # Replacement values.
1852
+ #
1853
+ # @return [Series]
1854
+ #
1855
+ # @example
1856
+ # s = Polars::Series.new("a", [1, 2, 3])
1857
+ # s.set_at_idx(1, 10)
1858
+ # # =>
1859
+ # # shape: (3,)
1860
+ # # Series: 'a' [i64]
1861
+ # # [
1862
+ # # 1
1863
+ # # 10
1864
+ # # 3
1865
+ # # ]
1866
+ def set_at_idx(idx, value)
1867
+ if idx.is_a?(Integer)
1868
+ idx = [idx]
1869
+ end
1870
+ if idx.length == 0
1871
+ return self
1872
+ end
1873
+
1874
+ idx = Series.new("", idx)
1875
+ if value.is_a?(Integer) || value.is_a?(Float) || Utils.bool?(value) || value.is_a?(String) || value.nil?
1876
+ value = Series.new("", [value])
1877
+
1878
+ # if we need to set more than a single value, we extend it
1879
+ if idx.length > 0
1880
+ value = value.extend_constant(value[0], idx.length - 1)
1881
+ end
1882
+ elsif !value.is_a?(Series)
1883
+ value = Series.new("", value)
1884
+ end
1885
+ _s.set_at_idx(idx._s, value._s)
1886
+ self
1887
+ end
1888
+
1889
+ # Create an empty copy of the current Series.
1890
+ #
1891
+ # The copy has identical name/dtype but no data.
1892
+ #
1893
+ # @return [Series]
1894
+ #
1895
+ # @example
1896
+ # s = Polars::Series.new("a", [nil, true, false])
1897
+ # s.cleared
1898
+ # # =>
1899
+ # # shape: (0,)
1900
+ # # Series: 'a' [bool]
1901
+ # # [
1902
+ # # ]
1903
+ def cleared
1904
+ len > 0 ? limit(0) : clone
1905
+ end
1906
+
1907
+ # clone handled by initialize_copy
1908
+
1909
+ # Fill floating point NaN value with a fill value.
1910
+ #
1911
+ # @param fill_value [Object]
1912
+ # Value used to fill nan values.
1913
+ #
1914
+ # @return [Series]
1915
+ #
1916
+ # @example
1917
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, Float::NAN])
1918
+ # s.fill_nan(0)
1919
+ # # =>
1920
+ # # shape: (4,)
1921
+ # # Series: 'a' [f64]
1922
+ # # [
1923
+ # # 1.0
1924
+ # # 2.0
1925
+ # # 3.0
1926
+ # # 0.0
1927
+ # # ]
1928
+ def fill_nan(fill_value)
1929
+ super
1930
+ end
1931
+
1932
+ # Fill null values using the specified value or strategy.
1933
+ #
1934
+ # @param value [Object]
1935
+ # Value used to fill null values.
1936
+ # @param strategy [nil, "forward", "backward", "min", "max", "mean", "zero", "one"]
1937
+ # Strategy used to fill null values.
1938
+ # @param limit
1939
+ # Number of consecutive null values to fill when using the "forward" or
1940
+ # "backward" strategy.
1941
+ #
1942
+ # @return [Series]
1943
+ #
1944
+ # @example
1945
+ # s = Polars::Series.new("a", [1, 2, 3, nil])
1946
+ # s.fill_null(strategy: "forward")
1947
+ # # =>
1948
+ # # shape: (4,)
1949
+ # # Series: 'a' [i64]
1950
+ # # [
1951
+ # # 1
1952
+ # # 2
1953
+ # # 3
1954
+ # # 3
1955
+ # # ]
1956
+ #
1957
+ # @example
1958
+ # s.fill_null(strategy: "min")
1959
+ # # =>
1960
+ # # shape: (4,)
1961
+ # # Series: 'a' [i64]
1962
+ # # [
1963
+ # # 1
1964
+ # # 2
1965
+ # # 3
1966
+ # # 1
1967
+ # # ]
1968
+ #
1969
+ # @example
1970
+ # s = Polars::Series.new("b", ["x", nil, "z"])
1971
+ # s.fill_null(Polars.lit(""))
1972
+ # # =>
1973
+ # # shape: (3,)
1974
+ # # Series: 'b' [str]
1975
+ # # [
1976
+ # # "x"
1977
+ # # ""
1978
+ # # "z"
1979
+ # # ]
1980
+ def fill_null(value = nil, strategy: nil, limit: nil)
1981
+ super
1982
+ end
1983
+
1984
+ # Rounds down to the nearest integer value.
1985
+ #
1986
+ # Only works on floating point Series.
1987
+ #
1988
+ # @return [Series]
1989
+ #
1990
+ # @example
1991
+ # s = Polars::Series.new("a", [1.12345, 2.56789, 3.901234])
1992
+ # s.floor
1993
+ # # =>
1994
+ # # shape: (3,)
1995
+ # # Series: 'a' [f64]
1996
+ # # [
1997
+ # # 1.0
1998
+ # # 2.0
1999
+ # # 3.0
2000
+ # # ]
2001
+ def floor
2002
+ Utils.wrap_s(_s.floor)
2003
+ end
2004
+
2005
+ # Rounds up to the nearest integer value.
2006
+ #
2007
+ # Only works on floating point Series.
2008
+ #
2009
+ # @return [Series]
2010
+ #
2011
+ # @example
2012
+ # s = Polars::Series.new("a", [1.12345, 2.56789, 3.901234])
2013
+ # s.ceil
2014
+ # # =>
2015
+ # # shape: (3,)
2016
+ # # Series: 'a' [f64]
2017
+ # # [
2018
+ # # 2.0
2019
+ # # 3.0
2020
+ # # 4.0
2021
+ # # ]
2022
+ def ceil
2023
+ super
2024
+ end
2025
+
2026
+ # Round underlying floating point data by `decimals` digits.
2027
+ #
2028
+ # @param decimals [Integer]
2029
+ # number of decimals to round by.
2030
+ #
2031
+ # @return [Series]
2032
+ #
2033
+ # @example
2034
+ # s = Polars::Series.new("a", [1.12345, 2.56789, 3.901234])
2035
+ # s.round(2)
2036
+ # # =>
2037
+ # # shape: (3,)
2038
+ # # Series: 'a' [f64]
2039
+ # # [
2040
+ # # 1.12
2041
+ # # 2.57
2042
+ # # 3.9
2043
+ # # ]
2044
+ def round(decimals = 0)
2045
+ super
2046
+ end
2047
+
2048
+ # Compute the dot/inner product between two Series.
2049
+ #
2050
+ # @param other [Object]
2051
+ # Series (or array) to compute dot product with.
2052
+ #
2053
+ # @return [Numeric]
2054
+ #
2055
+ # @example
2056
+ # s = Polars::Series.new("a", [1, 2, 3])
2057
+ # s2 = Polars::Series.new("b", [4.0, 5.0, 6.0])
2058
+ # s.dot(s2)
2059
+ # # => 32.0
2060
+ def dot(other)
2061
+ if !other.is_a?(Series)
2062
+ other = Series.new(other)
2063
+ end
2064
+ if len != other.len
2065
+ n, m = len, other.len
2066
+ raise ArgumentError, "Series length mismatch: expected #{n}, found #{m}"
2067
+ end
2068
+ _s.dot(other._s)
2069
+ end
2070
+
2071
+ # Compute the most occurring value(s).
2072
+ #
2073
+ # Can return multiple Values.
2074
+ #
2075
+ # @return [Series]
2076
+ #
2077
+ # @example
2078
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
2079
+ # s.mode
2080
+ # # =>
2081
+ # # shape: (1,)
2082
+ # # Series: 'a' [i64]
2083
+ # # [
2084
+ # # 2
2085
+ # # ]
2086
+ def mode
2087
+ super
2088
+ end
2089
+
2090
+ # Compute the element-wise indication of the sign.
2091
+ #
2092
+ # @return [Series]
2093
+ #
2094
+ # @example
2095
+ # s = Polars::Series.new("a", [-9.0, -0.0, 0.0, 4.0, nil])
2096
+ # s.sign
2097
+ # # =>
2098
+ # # shape: (5,)
2099
+ # # Series: 'a' [i64]
2100
+ # # [
2101
+ # # -1
2102
+ # # 0
2103
+ # # 0
2104
+ # # 1
2105
+ # # null
2106
+ # # ]
2107
+ def sign
2108
+ super
2109
+ end
2110
+
2111
+ # Compute the element-wise value for the sine.
2112
+ #
2113
+ # @return [Series]
2114
+ #
2115
+ # @example
2116
+ # s = Polars::Series.new("a", [0.0, Math::PI / 2.0, Math::PI])
2117
+ # s.sin
2118
+ # # =>
2119
+ # # shape: (3,)
2120
+ # # Series: 'a' [f64]
2121
+ # # [
2122
+ # # 0.0
2123
+ # # 1.0
2124
+ # # 1.2246e-16
2125
+ # # ]
2126
+ def sin
2127
+ super
2128
+ end
2129
+
2130
+ # Compute the element-wise value for the cosine.
2131
+ #
2132
+ # @return [Series]
2133
+ #
2134
+ # @example
2135
+ # s = Polars::Series.new("a", [0.0, Math::PI / 2.0, Math::PI])
2136
+ # s.cos
2137
+ # # =>
2138
+ # # shape: (3,)
2139
+ # # Series: 'a' [f64]
2140
+ # # [
2141
+ # # 1.0
2142
+ # # 6.1232e-17
2143
+ # # -1.0
2144
+ # # ]
2145
+ def cos
2146
+ super
2147
+ end
2148
+
2149
+ # Compute the element-wise value for the tangent.
2150
+ #
2151
+ # @return [Series]
2152
+ #
2153
+ # @example
2154
+ # s = Polars::Series.new("a", [0.0, Math::PI / 2.0, Math::PI])
2155
+ # s.tan
2156
+ # # =>
2157
+ # # shape: (3,)
2158
+ # # Series: 'a' [f64]
2159
+ # # [
2160
+ # # 0.0
2161
+ # # 1.6331e16
2162
+ # # -1.2246e-16
2163
+ # # ]
2164
+ def tan
2165
+ super
2166
+ end
2167
+
2168
+ # Compute the element-wise value for the inverse sine.
2169
+ #
2170
+ # @return [Series]
2171
+ #
2172
+ # @example
2173
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2174
+ # s.arcsin
2175
+ # # =>
2176
+ # # shape: (3,)
2177
+ # # Series: 'a' [f64]
2178
+ # # [
2179
+ # # 1.570796
2180
+ # # 0.0
2181
+ # # -1.570796
2182
+ # # ]
2183
+ def arcsin
2184
+ super
2185
+ end
2186
+
2187
+ # Compute the element-wise value for the inverse cosine.
2188
+ #
2189
+ # @return [Series]
2190
+ #
2191
+ # @example
2192
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2193
+ # s.arccos
2194
+ # # =>
2195
+ # # shape: (3,)
2196
+ # # Series: 'a' [f64]
2197
+ # # [
2198
+ # # 0.0
2199
+ # # 1.570796
2200
+ # # 3.141593
2201
+ # # ]
2202
+ def arccos
2203
+ super
2204
+ end
2205
+
2206
+ # Compute the element-wise value for the inverse tangent.
2207
+ #
2208
+ # @return [Series]
2209
+ #
2210
+ # @example
2211
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2212
+ # s.arctan
2213
+ # # =>
2214
+ # # shape: (3,)
2215
+ # # Series: 'a' [f64]
2216
+ # # [
2217
+ # # 0.785398
2218
+ # # 0.0
2219
+ # # -0.785398
2220
+ # # ]
2221
+ def arctan
2222
+ super
2223
+ end
2224
+
2225
+ # Compute the element-wise value for the inverse hyperbolic sine.
2226
+ #
2227
+ # @return [Series]
2228
+ #
2229
+ # @example
2230
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2231
+ # s.arcsinh
2232
+ # # =>
2233
+ # # shape: (3,)
2234
+ # # Series: 'a' [f64]
2235
+ # # [
2236
+ # # 0.881374
2237
+ # # 0.0
2238
+ # # -0.881374
2239
+ # # ]
2240
+ def arcsinh
2241
+ super
2242
+ end
2243
+
2244
+ # Compute the element-wise value for the inverse hyperbolic cosine.
2245
+ #
2246
+ # @return [Series]
2247
+ #
2248
+ # @example
2249
+ # s = Polars::Series.new("a", [5.0, 1.0, 0.0, -1.0])
2250
+ # s.arccosh
2251
+ # # =>
2252
+ # # shape: (4,)
2253
+ # # Series: 'a' [f64]
2254
+ # # [
2255
+ # # 2.292432
2256
+ # # 0.0
2257
+ # # NaN
2258
+ # # NaN
2259
+ # # ]
2260
+ def arccosh
2261
+ super
2262
+ end
2263
+
2264
+ # Compute the element-wise value for the inverse hyperbolic tangent.
2265
+ #
2266
+ # @return [Series]
2267
+ #
2268
+ # @example
2269
+ # s = Polars::Series.new("a", [2.0, 1.0, 0.5, 0.0, -0.5, -1.0, -1.1])
2270
+ # s.arctanh
2271
+ # # =>
2272
+ # # shape: (7,)
2273
+ # # Series: 'a' [f64]
2274
+ # # [
2275
+ # # NaN
2276
+ # # inf
2277
+ # # 0.549306
2278
+ # # 0.0
2279
+ # # -0.549306
2280
+ # # -inf
2281
+ # # NaN
2282
+ # # ]
2283
+ def arctanh
2284
+ super
2285
+ end
2286
+
2287
+ # Compute the element-wise value for the hyperbolic sine.
2288
+ #
2289
+ # @return [Series]
2290
+ #
2291
+ # @example
2292
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2293
+ # s.sinh
2294
+ # # =>
2295
+ # # shape: (3,)
2296
+ # # Series: 'a' [f64]
2297
+ # # [
2298
+ # # 1.175201
2299
+ # # 0.0
2300
+ # # -1.175201
2301
+ # # ]
2302
+ def sinh
2303
+ super
2304
+ end
2305
+
2306
+ # Compute the element-wise value for the hyperbolic cosine.
2307
+ #
2308
+ # @return [Series]
2309
+ #
2310
+ # @example
2311
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2312
+ # s.cosh
2313
+ # # =>
2314
+ # # shape: (3,)
2315
+ # # Series: 'a' [f64]
2316
+ # # [
2317
+ # # 1.543081
2318
+ # # 1.0
2319
+ # # 1.543081
2320
+ # # ]
2321
+ def cosh
2322
+ super
2323
+ end
2324
+
2325
+ # Compute the element-wise value for the hyperbolic tangent.
2326
+ #
2327
+ # @return [Series]
2328
+ #
2329
+ # @example
2330
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2331
+ # s.tanh
2332
+ # # =>
2333
+ # # shape: (3,)
2334
+ # # Series: 'a' [f64]
2335
+ # # [
2336
+ # # 0.761594
2337
+ # # 0.0
2338
+ # # -0.761594
2339
+ # # ]
2340
+ def tanh
2341
+ super
2342
+ end
2343
+
2344
+ # Apply a custom/user-defined function (UDF) over elements in this Series and
2345
+ # return a new Series.
2346
+ #
2347
+ # If the function returns another datatype, the return_dtype arg should be set,
2348
+ # otherwise the method will fail.
2349
+ #
2350
+ # @param return_dtype [Symbol]
2351
+ # Output datatype. If none is given, the same datatype as this Series will be
2352
+ # used.
2353
+ # @param skip_nulls [Boolean]
2354
+ # Nulls will be skipped and not passed to the Ruby function.
2355
+ # This is faster because Ruby can be skipped and because we call
2356
+ # more specialized functions.
2357
+ #
2358
+ # @return [Series]
2359
+ #
2360
+ # @example
2361
+ # s = Polars::Series.new("a", [1, 2, 3])
2362
+ # s.apply { |x| x + 10 }
2363
+ # # =>
2364
+ # # shape: (3,)
2365
+ # # Series: 'a' [i64]
2366
+ # # [
2367
+ # # 11
2368
+ # # 12
2369
+ # # 13
2370
+ # # ]
2371
+ def apply(return_dtype: nil, skip_nulls: true, &func)
2372
+ if return_dtype.nil?
2373
+ pl_return_dtype = nil
2374
+ else
2375
+ pl_return_dtype = Utils.rb_type_to_dtype(return_dtype)
2376
+ end
2377
+ Utils.wrap_s(_s.apply_lambda(func, pl_return_dtype, skip_nulls))
2378
+ end
2379
+
2380
+ # Shift the values by a given period.
2381
+ #
2382
+ # @param periods [Integer]
2383
+ # Number of places to shift (may be negative).
2384
+ #
2385
+ # @return [Series]
2386
+ #
2387
+ # @example
2388
+ # s = Polars::Series.new("a", [1, 2, 3])
2389
+ # s.shift(1)
2390
+ # # =>
2391
+ # # shape: (3,)
2392
+ # # Series: 'a' [i64]
2393
+ # # [
2394
+ # # null
2395
+ # # 1
2396
+ # # 2
2397
+ # # ]
2398
+ #
2399
+ # @example
2400
+ # s.shift(-1)
2401
+ # # =>
2402
+ # # shape: (3,)
2403
+ # # Series: 'a' [i64]
2404
+ # # [
2405
+ # # 2
2406
+ # # 3
2407
+ # # null
2408
+ # # ]
2409
+ def shift(periods = 1)
2410
+ super
2411
+ end
2412
+
2413
+ # Shift the values by a given period and fill the resulting null values.
2414
+ #
2415
+ # @param periods [Integer]
2416
+ # Number of places to shift (may be negative).
2417
+ # @param fill_value [Object]
2418
+ # Fill None values with the result of this expression.
2419
+ #
2420
+ # @return [Series]
2421
+ def shift_and_fill(periods, fill_value)
2422
+ super
2423
+ end
2424
+
2425
+ # Take values from self or other based on the given mask.
2426
+ #
2427
+ # Where mask evaluates true, take values from self. Where mask evaluates false,
2428
+ # take values from other.
2429
+ #
2430
+ # @param mask [Series]
2431
+ # Boolean Series.
2432
+ # @param other [Series]
2433
+ # Series of same type.
2434
+ #
2435
+ # @return [Series]
2436
+ #
2437
+ # @example
2438
+ # s1 = Polars::Series.new([1, 2, 3, 4, 5])
2439
+ # s2 = Polars::Series.new([5, 4, 3, 2, 1])
2440
+ # s1.zip_with(s1 < s2, s2)
2441
+ # # =>
2442
+ # # shape: (5,)
2443
+ # # Series: '' [i64]
2444
+ # # [
2445
+ # # 1
2446
+ # # 2
2447
+ # # 3
2448
+ # # 2
2449
+ # # 1
2450
+ # # ]
2451
+ #
2452
+ # @example
2453
+ # mask = Polars::Series.new([true, false, true, false, true])
2454
+ # s1.zip_with(mask, s2)
2455
+ # # =>
2456
+ # # shape: (5,)
2457
+ # # Series: '' [i64]
2458
+ # # [
2459
+ # # 1
2460
+ # # 4
2461
+ # # 3
2462
+ # # 2
2463
+ # # 5
2464
+ # # ]
2465
+ def zip_with(mask, other)
2466
+ Utils.wrap_s(_s.zip_with(mask._s, other._s))
2467
+ end
2468
+
2469
+ # Apply a rolling min (moving min) over the values in this array.
2470
+ #
2471
+ # A window of length `window_size` will traverse the array. The values that fill
2472
+ # this window will (optionally) be multiplied with the weights given by the
2473
+ # `weight` vector. The resulting values will be aggregated to their sum.
2474
+ #
2475
+ # @param window_size [Integer]
2476
+ # The length of the window.
2477
+ # @param weights [Array]
2478
+ # An optional slice with the same length as the window that will be multiplied
2479
+ # elementwise with the values in the window.
2480
+ # @param min_periods [Integer]
2481
+ # The number of values in the window that should be non-null before computing
2482
+ # a result. If None, it will be set equal to window size.
2483
+ # @param center [Boolean]
2484
+ # Set the labels at the center of the window
2485
+ #
2486
+ # @return [Series]
2487
+ #
2488
+ # @example
2489
+ # s = Polars::Series.new("a", [100, 200, 300, 400, 500])
2490
+ # s.rolling_min(3)
2491
+ # # =>
2492
+ # # shape: (5,)
2493
+ # # Series: 'a' [i64]
2494
+ # # [
2495
+ # # null
2496
+ # # null
2497
+ # # 100
2498
+ # # 200
2499
+ # # 300
2500
+ # # ]
2501
+ def rolling_min(
2502
+ window_size,
2503
+ weights: nil,
2504
+ min_periods: nil,
2505
+ center: false
2506
+ )
2507
+ to_frame
2508
+ .select(
2509
+ Polars.col(name).rolling_min(
2510
+ window_size,
2511
+ weights: weights,
2512
+ min_periods: min_periods,
2513
+ center: center
2514
+ )
2515
+ )
2516
+ .to_series
2517
+ end
2518
+
2519
+ # Apply a rolling max (moving max) over the values in this array.
2520
+ #
2521
+ # A window of length `window_size` will traverse the array. The values that fill
2522
+ # this window will (optionally) be multiplied with the weights given by the
2523
+ # `weight` vector. The resulting values will be aggregated to their sum.
2524
+ #
2525
+ # @param window_size [Integer]
2526
+ # The length of the window.
2527
+ # @param weights [Array]
2528
+ # An optional slice with the same length as the window that will be multiplied
2529
+ # elementwise with the values in the window.
2530
+ # @param min_periods [Integer]
2531
+ # The number of values in the window that should be non-null before computing
2532
+ # a result. If None, it will be set equal to window size.
2533
+ # @param center [Boolean]
2534
+ # Set the labels at the center of the window
2535
+ #
2536
+ # @return [Series]
2537
+ #
2538
+ # @example
2539
+ # s = Polars::Series.new("a", [100, 200, 300, 400, 500])
2540
+ # s.rolling_max(2)
2541
+ # # =>
2542
+ # # shape: (5,)
2543
+ # # Series: 'a' [i64]
2544
+ # # [
2545
+ # # null
2546
+ # # 200
2547
+ # # 300
2548
+ # # 400
2549
+ # # 500
2550
+ # # ]
2551
+ def rolling_max(
2552
+ window_size,
2553
+ weights: nil,
2554
+ min_periods: nil,
2555
+ center: false
2556
+ )
2557
+ to_frame
2558
+ .select(
2559
+ Polars.col(name).rolling_max(
2560
+ window_size,
2561
+ weights: weights,
2562
+ min_periods: min_periods,
2563
+ center: center
2564
+ )
2565
+ )
2566
+ .to_series
2567
+ end
2568
+
2569
+ # Apply a rolling mean (moving mean) over the values in this array.
2570
+ #
2571
+ # A window of length `window_size` will traverse the array. The values that fill
2572
+ # this window will (optionally) be multiplied with the weights given by the
2573
+ # `weight` vector. The resulting values will be aggregated to their sum.
2574
+ #
2575
+ # @param window_size [Integer]
2576
+ # The length of the window.
2577
+ # @param weights [Array]
2578
+ # An optional slice with the same length as the window that will be multiplied
2579
+ # elementwise with the values in the window.
2580
+ # @param min_periods [Integer]
2581
+ # The number of values in the window that should be non-null before computing
2582
+ # a result. If None, it will be set equal to window size.
2583
+ # @param center [Boolean]
2584
+ # Set the labels at the center of the window
2585
+ #
2586
+ # @return [Series]
2587
+ #
2588
+ # @example
2589
+ # s = Polars::Series.new("a", [100, 200, 300, 400, 500])
2590
+ # s.rolling_mean(2)
2591
+ # # =>
2592
+ # # shape: (5,)
2593
+ # # Series: 'a' [f64]
2594
+ # # [
2595
+ # # null
2596
+ # # 150.0
2597
+ # # 250.0
2598
+ # # 350.0
2599
+ # # 450.0
2600
+ # # ]
2601
+ def rolling_mean(
2602
+ window_size,
2603
+ weights: nil,
2604
+ min_periods: nil,
2605
+ center: false
2606
+ )
2607
+ to_frame
2608
+ .select(
2609
+ Polars.col(name).rolling_mean(
2610
+ window_size,
2611
+ weights: weights,
2612
+ min_periods: min_periods,
2613
+ center: center
2614
+ )
2615
+ )
2616
+ .to_series
2617
+ end
2618
+
2619
+ # Apply a rolling sum (moving sum) over the values in this array.
2620
+ #
2621
+ # A window of length `window_size` will traverse the array. The values that fill
2622
+ # this window will (optionally) be multiplied with the weights given by the
2623
+ # `weight` vector. The resulting values will be aggregated to their sum.
2624
+ #
2625
+ # @param window_size [Integer]
2626
+ # The length of the window.
2627
+ # @param weights [Array]
2628
+ # An optional slice with the same length as the window that will be multiplied
2629
+ # elementwise with the values in the window.
2630
+ # @param min_periods [Integer]
2631
+ # The number of values in the window that should be non-null before computing
2632
+ # a result. If None, it will be set equal to window size.
2633
+ # @param center [Boolean]
2634
+ # Set the labels at the center of the window
2635
+ #
2636
+ # @return [Series]
2637
+ #
2638
+ # @example
2639
+ # s = Polars::Series.new("a", [1, 2, 3, 4, 5])
2640
+ # s.rolling_sum(2)
2641
+ # # =>
2642
+ # # shape: (5,)
2643
+ # # Series: 'a' [i64]
2644
+ # # [
2645
+ # # null
2646
+ # # 3
2647
+ # # 5
2648
+ # # 7
2649
+ # # 9
2650
+ # # ]
2651
+ def rolling_sum(
2652
+ window_size,
2653
+ weights: nil,
2654
+ min_periods: nil,
2655
+ center: false
2656
+ )
2657
+ to_frame
2658
+ .select(
2659
+ Polars.col(name).rolling_sum(
2660
+ window_size,
2661
+ weights: weights,
2662
+ min_periods: min_periods,
2663
+ center: center
2664
+ )
2665
+ )
2666
+ .to_series
2667
+ end
2668
+
2669
+ # Compute a rolling std dev.
2670
+ #
2671
+ # A window of length `window_size` will traverse the array. The values that fill
2672
+ # this window will (optionally) be multiplied with the weights given by the
2673
+ # `weight` vector. The resulting values will be aggregated to their sum.
2674
+ #
2675
+ # @param window_size [Integer]
2676
+ # The length of the window.
2677
+ # @param weights [Array]
2678
+ # An optional slice with the same length as the window that will be multiplied
2679
+ # elementwise with the values in the window.
2680
+ # @param min_periods [Integer]
2681
+ # The number of values in the window that should be non-null before computing
2682
+ # a result. If None, it will be set equal to window size.
2683
+ # @param center [Boolean]
2684
+ # Set the labels at the center of the window
2685
+ #
2686
+ # @return [Series]
2687
+ #
2688
+ # @example
2689
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, 4.0, 6.0, 8.0])
2690
+ # s.rolling_std(3)
2691
+ # # =>
2692
+ # # shape: (6,)
2693
+ # # Series: 'a' [f64]
2694
+ # # [
2695
+ # # null
2696
+ # # null
2697
+ # # 1.0
2698
+ # # 1.0
2699
+ # # 1.527525
2700
+ # # 2.0
2701
+ # # ]
2702
+ def rolling_std(
2703
+ window_size,
2704
+ weights: nil,
2705
+ min_periods: nil,
2706
+ center: false
2707
+ )
2708
+ to_frame
2709
+ .select(
2710
+ Polars.col(name).rolling_std(
2711
+ window_size,
2712
+ weights: weights,
2713
+ min_periods: min_periods,
2714
+ center: center
2715
+ )
2716
+ )
2717
+ .to_series
2718
+ end
2719
+
2720
+ # Compute a rolling variance.
2721
+ #
2722
+ # A window of length `window_size` will traverse the array. The values that fill
2723
+ # this window will (optionally) be multiplied with the weights given by the
2724
+ # `weight` vector. The resulting values will be aggregated to their sum.
2725
+ #
2726
+ # @param window_size [Integer]
2727
+ # The length of the window.
2728
+ # @param weights [Array]
2729
+ # An optional slice with the same length as the window that will be multiplied
2730
+ # elementwise with the values in the window.
2731
+ # @param min_periods [Integer]
2732
+ # The number of values in the window that should be non-null before computing
2733
+ # a result. If None, it will be set equal to window size.
2734
+ # @param center [Boolean]
2735
+ # Set the labels at the center of the window
2736
+ #
2737
+ # @return [Series]
2738
+ #
2739
+ # @example
2740
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, 4.0, 6.0, 8.0])
2741
+ # s.rolling_var(3)
2742
+ # # =>
2743
+ # # shape: (6,)
2744
+ # # Series: 'a' [f64]
2745
+ # # [
2746
+ # # null
2747
+ # # null
2748
+ # # 1.0
2749
+ # # 1.0
2750
+ # # 2.333333
2751
+ # # 4.0
2752
+ # # ]
2753
+ def rolling_var(
2754
+ window_size,
2755
+ weights: nil,
2756
+ min_periods: nil,
2757
+ center: false
2758
+ )
2759
+ to_frame
2760
+ .select(
2761
+ Polars.col(name).rolling_var(
2762
+ window_size,
2763
+ weights: weights,
2764
+ min_periods: min_periods,
2765
+ center: center
2766
+ )
2767
+ )
2768
+ .to_series
2769
+ end
2770
+
2771
+ # def rolling_apply
2772
+ # end
2773
+
2774
+ # Compute a rolling median.
2775
+ #
2776
+ # @param window_size [Integer]
2777
+ # The length of the window.
2778
+ # @param weights [Array]
2779
+ # An optional slice with the same length as the window that will be multiplied
2780
+ # elementwise with the values in the window.
2781
+ # @param min_periods [Integer]
2782
+ # The number of values in the window that should be non-null before computing
2783
+ # a result. If None, it will be set equal to window size.
2784
+ # @param center [Boolean]
2785
+ # Set the labels at the center of the window
2786
+ #
2787
+ # @return [Series]
2788
+ #
2789
+ # @example
2790
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, 4.0, 6.0, 8.0])
2791
+ # s.rolling_median(3)
2792
+ # # =>
2793
+ # # shape: (6,)
2794
+ # # Series: 'a' [f64]
2795
+ # # [
2796
+ # # null
2797
+ # # null
2798
+ # # 2.0
2799
+ # # 3.0
2800
+ # # 4.0
2801
+ # # 6.0
2802
+ # # ]
2803
+ def rolling_median(
2804
+ window_size,
2805
+ weights: nil,
2806
+ min_periods: nil,
2807
+ center: false
2808
+ )
2809
+ if min_periods.nil?
2810
+ min_periods = window_size
2811
+ end
2812
+
2813
+ to_frame
2814
+ .select(
2815
+ Polars.col(name).rolling_median(
2816
+ window_size,
2817
+ weights: weights,
2818
+ min_periods: min_periods,
2819
+ center: center
2820
+ )
2821
+ )
2822
+ .to_series
2823
+ end
2824
+
2825
+ # Compute a rolling quantile.
2826
+ #
2827
+ # @param quantile [Float]
2828
+ # Quantile between 0.0 and 1.0.
2829
+ # @param interpolation ["nearest", "higher", "lower", "midpoint", "linear"]
2830
+ # Interpolation method.
2831
+ # @param window_size [Integer]
2832
+ # The length of the window.
2833
+ # @param weights [Array]
2834
+ # An optional slice with the same length as the window that will be multiplied
2835
+ # elementwise with the values in the window.
2836
+ # @param min_periods [Integer]
2837
+ # The number of values in the window that should be non-null before computing
2838
+ # a result. If None, it will be set equal to window size.
2839
+ # @param center [Boolean]
2840
+ # Set the labels at the center of the window
2841
+ #
2842
+ # @return [Series]
2843
+ #
2844
+ # @example
2845
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, 4.0, 6.0, 8.0])
2846
+ # s.rolling_quantile(0.33, window_size: 3)
2847
+ # # =>
2848
+ # # shape: (6,)
2849
+ # # Series: 'a' [f64]
2850
+ # # [
2851
+ # # null
2852
+ # # null
2853
+ # # 1.0
2854
+ # # 2.0
2855
+ # # 3.0
2856
+ # # 4.0
2857
+ # # ]
2858
+ #
2859
+ # @example
2860
+ # s.rolling_quantile(0.33, interpolation: "linear", window_size: 3)
2861
+ # # =>
2862
+ # # shape: (6,)
2863
+ # # Series: 'a' [f64]
2864
+ # # [
2865
+ # # null
2866
+ # # null
2867
+ # # 1.66
2868
+ # # 2.66
2869
+ # # 3.66
2870
+ # # 5.32
2871
+ # # ]
2872
+ def rolling_quantile(
2873
+ quantile,
2874
+ interpolation: "nearest",
2875
+ window_size: 2,
2876
+ weights: nil,
2877
+ min_periods: nil,
2878
+ center: false
2879
+ )
2880
+ if min_periods.nil?
2881
+ min_periods = window_size
2882
+ end
2883
+
2884
+ to_frame
2885
+ .select(
2886
+ Polars.col(name).rolling_quantile(
2887
+ quantile,
2888
+ interpolation: interpolation,
2889
+ window_size: window_size,
2890
+ weights: weights,
2891
+ min_periods: min_periods,
2892
+ center: center
2893
+ )
2894
+ )
2895
+ .to_series
2896
+ end
2897
+
2898
+ # Compute a rolling skew.
2899
+ #
2900
+ # @param window_size [Integer]
2901
+ # Integer size of the rolling window.
2902
+ # @param bias [Boolean]
2903
+ # If false, the calculations are corrected for statistical bias.
2904
+ #
2905
+ # @return [Series]
2906
+ #
2907
+ # @example
2908
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, 4.0, 6.0, 8.0])
2909
+ # s.rolling_skew(3)
2910
+ # # =>
2911
+ # # shape: (6,)
2912
+ # # Series: 'a' [f64]
2913
+ # # [
2914
+ # # null
2915
+ # # null
2916
+ # # 0.0
2917
+ # # 0.0
2918
+ # # 0.381802
2919
+ # # 0.0
2920
+ # # ]
2921
+ def rolling_skew(window_size, bias: true)
2922
+ super
2923
+ end
2924
+
2925
+ # Sample from this Series.
2926
+ #
2927
+ # @param n [Integer]
2928
+ # Number of items to return. Cannot be used with `frac`. Defaults to 1 if
2929
+ # `frac` is None.
2930
+ # @param frac [Float]
2931
+ # Fraction of items to return. Cannot be used with `n`.
2932
+ # @param with_replacement [Boolean]
2933
+ # Allow values to be sampled more than once.
2934
+ # @param shuffle [Boolean]
2935
+ # Shuffle the order of sampled data points.
2936
+ # @param seed [Integer]
2937
+ # Seed for the random number generator. If set to None (default), a random
2938
+ # seed is used.
2939
+ #
2940
+ # @return [Series]
2941
+ #
2942
+ # @example
2943
+ # s = Polars::Series.new("a", [1, 2, 3, 4, 5])
2944
+ # s.sample(n: 2, seed: 0)
2945
+ # # =>
2946
+ # # shape: (2,)
2947
+ # # Series: 'a' [i64]
2948
+ # # [
2949
+ # # 1
2950
+ # # 5
2951
+ # # ]
2952
+ def sample(
2953
+ n: nil,
2954
+ frac: nil,
2955
+ with_replacement: false,
2956
+ shuffle: false,
2957
+ seed: nil
2958
+ )
2959
+ if !n.nil? && !frac.nil?
2960
+ raise ArgumentError, "cannot specify both `n` and `frac`"
2961
+ end
2962
+
2963
+ if n.nil? && !frac.nil?
2964
+ return Utils.wrap_s(_s.sample_frac(frac, with_replacement, shuffle, seed))
2965
+ end
2966
+
2967
+ if n.nil?
2968
+ n = 1
2969
+ end
2970
+ Utils.wrap_s(_s.sample_n(n, with_replacement, shuffle, seed))
2971
+ end
2972
+
2973
+ # Get a boolean mask of the local maximum peaks.
2974
+ #
2975
+ # @return [Series]
2976
+ #
2977
+ # @example
2978
+ # s = Polars::Series.new("a", [1, 2, 3, 4, 5])
2979
+ # s.peak_max
2980
+ # # =>
2981
+ # # shape: (5,)
2982
+ # # Series: '' [bool]
2983
+ # # [
2984
+ # # false
2985
+ # # false
2986
+ # # false
2987
+ # # false
2988
+ # # true
2989
+ # # ]
2990
+ def peak_max
2991
+ Utils.wrap_s(_s.peak_max)
2992
+ end
2993
+
2994
+ # Get a boolean mask of the local minimum peaks.
2995
+ #
2996
+ # @return [Series]
2997
+ #
2998
+ # @example
2999
+ # s = Polars::Series.new("a", [4, 1, 3, 2, 5])
3000
+ # s.peak_min
3001
+ # # =>
3002
+ # # shape: (5,)
3003
+ # # Series: '' [bool]
3004
+ # # [
3005
+ # # false
3006
+ # # true
3007
+ # # false
3008
+ # # true
3009
+ # # false
3010
+ # # ]
3011
+ def peak_min
3012
+ Utils.wrap_s(_s.peak_min)
3013
+ end
3014
+
3015
+ # Count the number of unique values in this Series.
3016
+ #
3017
+ # @return [Integer]
3018
+ #
3019
+ # @example
3020
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
3021
+ # s.n_unique
3022
+ # # => 3
3023
+ def n_unique
3024
+ _s.n_unique
3025
+ end
3026
+
3027
+ # Shrink Series memory usage.
3028
+ #
3029
+ # Shrinks the underlying array capacity to exactly fit the actual data.
3030
+ # (Note that this function does not change the Series data type).
3031
+ #
3032
+ # @return [Series]
3033
+ def shrink_to_fit(in_place: false)
3034
+ if in_place
3035
+ _s.shrink_to_fit
3036
+ self
3037
+ else
3038
+ series = clone
3039
+ series._s.shrink_to_fit
3040
+ series
3041
+ end
3042
+ end
3043
+
3044
+ # Hash the Series.
3045
+ #
3046
+ # The hash value is of type `:u64`.
3047
+ #
3048
+ # @param seed [Integer]
3049
+ # Random seed parameter. Defaults to 0.
3050
+ # @param seed_1 [Integer]
3051
+ # Random seed parameter. Defaults to `seed` if not set.
3052
+ # @param seed_2 [Integer]
3053
+ # Random seed parameter. Defaults to `seed` if not set.
3054
+ # @param seed_3 [Integer]
3055
+ # Random seed parameter. Defaults to `seed` if not set.
3056
+ #
3057
+ # @return [Series]
3058
+ #
3059
+ # @example
3060
+ # s = Polars::Series.new("a", [1, 2, 3])
3061
+ # s._hash(42)
3062
+ # # =>
3063
+ # # shape: (3,)
3064
+ # # Series: 'a' [u64]
3065
+ # # [
3066
+ # # 2374023516666777365
3067
+ # # 10386026231460783898
3068
+ # # 17796317186427479491
3069
+ # # ]
3070
+ def _hash(seed = 0, seed_1 = nil, seed_2 = nil, seed_3 = nil)
3071
+ super
3072
+ end
3073
+
3074
+ # Reinterpret the underlying bits as a signed/unsigned integer.
3075
+ #
3076
+ # This operation is only allowed for 64bit integers. For lower bits integers,
3077
+ # you can safely use that cast operation.
3078
+ #
3079
+ # @param signed [Boolean]
3080
+ # If true, reinterpret as `:i64`. Otherwise, reinterpret as `:u64`.
3081
+ #
3082
+ # @return [Series]
3083
+ def reinterpret(signed: true)
3084
+ super
3085
+ end
3086
+
3087
+ # Interpolate intermediate values. The interpolation method is linear.
3088
+ #
3089
+ # @return [Series]
3090
+ #
3091
+ # @example
3092
+ # s = Polars::Series.new("a", [1, 2, nil, nil, 5])
3093
+ # s.interpolate
3094
+ # # =>
3095
+ # # shape: (5,)
3096
+ # # Series: 'a' [i64]
3097
+ # # [
3098
+ # # 1
3099
+ # # 2
3100
+ # # 3
3101
+ # # 4
3102
+ # # 5
3103
+ # # ]
3104
+ def interpolate(method: "linear")
3105
+ super
3106
+ end
3107
+
3108
+ # Compute absolute values.
3109
+ #
3110
+ # @return [Series]
3111
+ def abs
3112
+ super
3113
+ end
3114
+
3115
+ # Assign ranks to data, dealing with ties appropriately.
3116
+ #
3117
+ # @param method ["average", "min", "max", "dense", "ordinal", "random"]
3118
+ # The method used to assign ranks to tied elements.
3119
+ # The following methods are available (default is 'average'):
3120
+ #
3121
+ # - 'average' : The average of the ranks that would have been assigned to
3122
+ # all the tied values is assigned to each value.
3123
+ # - 'min' : The minimum of the ranks that would have been assigned to all
3124
+ # the tied values is assigned to each value. (This is also referred to
3125
+ # as "competition" ranking.)
3126
+ # - 'max' : The maximum of the ranks that would have been assigned to all
3127
+ # the tied values is assigned to each value.
3128
+ # - 'dense' : Like 'min', but the rank of the next highest element is
3129
+ # assigned the rank immediately after those assigned to the tied
3130
+ # elements.
3131
+ # - 'ordinal' : All values are given a distinct rank, corresponding to
3132
+ # the order that the values occur in the Series.
3133
+ # - 'random' : Like 'ordinal', but the rank for ties is not dependent
3134
+ # on the order that the values occur in the Series.
3135
+ # @param reverse [Boolean]
3136
+ # Reverse the operation.
3137
+ #
3138
+ # @return [Series]
3139
+ #
3140
+ # @example The 'average' method:
3141
+ # s = Polars::Series.new("a", [3, 6, 1, 1, 6])
3142
+ # s.rank
3143
+ # # =>
3144
+ # # shape: (5,)
3145
+ # # Series: 'a' [f32]
3146
+ # # [
3147
+ # # 3.0
3148
+ # # 4.5
3149
+ # # 1.5
3150
+ # # 1.5
3151
+ # # 4.5
3152
+ # # ]
3153
+ #
3154
+ # @example The 'ordinal' method:
3155
+ # s = Polars::Series.new("a", [3, 6, 1, 1, 6])
3156
+ # s.rank(method: "ordinal")
3157
+ # # =>
3158
+ # # shape: (5,)
3159
+ # # Series: 'a' [u32]
3160
+ # # [
3161
+ # # 3
3162
+ # # 4
3163
+ # # 1
3164
+ # # 2
3165
+ # # 5
3166
+ # # ]
3167
+ def rank(method: "average", reverse: false)
3168
+ super
3169
+ end
3170
+
3171
+ # Calculate the n-th discrete difference.
3172
+ #
3173
+ # @param n [Integer]
3174
+ # Number of slots to shift.
3175
+ # @param null_behavior ["ignore", "drop"]
3176
+ # How to handle null values.
3177
+ #
3178
+ # @return [Series]
3179
+ def diff(n: 1, null_behavior: "ignore")
3180
+ super
3181
+ end
3182
+
3183
+ # Computes percentage change between values.
3184
+ #
3185
+ # Percentage change (as fraction) between current element and most-recent
3186
+ # non-null element at least `n` period(s) before the current element.
3187
+ #
3188
+ # Computes the change from the previous row by default.
3189
+ #
3190
+ # @param n [Integer]
3191
+ # periods to shift for forming percent change.
3192
+ #
3193
+ # @return [Series]
3194
+ #
3195
+ # @example
3196
+ # Polars::Series.new(0..9).pct_change
3197
+ # # =>
3198
+ # # shape: (10,)
3199
+ # # Series: '' [f64]
3200
+ # # [
3201
+ # # null
3202
+ # # inf
3203
+ # # 1.0
3204
+ # # 0.5
3205
+ # # 0.333333
3206
+ # # 0.25
3207
+ # # 0.2
3208
+ # # 0.166667
3209
+ # # 0.142857
3210
+ # # 0.125
3211
+ # # ]
3212
+ #
3213
+ # @example
3214
+ # Polars::Series.new([1, 2, 4, 8, 16, 32, 64, 128, 256, 512]).pct_change(n: 2)
3215
+ # # =>
3216
+ # # shape: (10,)
3217
+ # # Series: '' [f64]
3218
+ # # [
3219
+ # # null
3220
+ # # null
3221
+ # # 3.0
3222
+ # # 3.0
3223
+ # # 3.0
3224
+ # # 3.0
3225
+ # # 3.0
3226
+ # # 3.0
3227
+ # # 3.0
3228
+ # # 3.0
3229
+ # # ]
3230
+ def pct_change(n: 1)
3231
+ super
3232
+ end
3233
+
3234
+ # Compute the sample skewness of a data set.
3235
+ #
3236
+ # For normally distributed data, the skewness should be about zero. For
3237
+ # unimodal continuous distributions, a skewness value greater than zero means
3238
+ # that there is more weight in the right tail of the distribution. The
3239
+ # function `skewtest` can be used to determine if the skewness value
3240
+ # is close enough to zero, statistically speaking.
3241
+ #
3242
+ # @param bias [Boolean]
3243
+ # If `false`, the calculations are corrected for statistical bias.
3244
+ #
3245
+ # @return [Float, nil]
3246
+ def skew(bias: true)
3247
+ _s.skew(bias)
3248
+ end
3249
+
3250
+ # Compute the kurtosis (Fisher or Pearson) of a dataset.
3251
+ #
3252
+ # Kurtosis is the fourth central moment divided by the square of the
3253
+ # variance. If Fisher's definition is used, then 3.0 is subtracted from
3254
+ # the result to give 0.0 for a normal distribution.
3255
+ # If bias is false, then the kurtosis is calculated using k statistics to
3256
+ # eliminate bias coming from biased moment estimators
3257
+ #
3258
+ # @param fisher [Boolean]
3259
+ # If `true`, Fisher's definition is used (normal ==> 0.0). If `false`,
3260
+ # Pearson's definition is used (normal ==> 3.0).
3261
+ # @param bias [Boolean]
3262
+ # If `false`, the calculations are corrected for statistical bias.
3263
+ #
3264
+ # @return [Float, nil]
3265
+ def kurtosis(fisher: true, bias: true)
3266
+ _s.kurtosis(fisher, bias)
3267
+ end
3268
+
3269
+ # Clip (limit) the values in an array to a `min` and `max` boundary.
3270
+ #
3271
+ # Only works for numerical types.
3272
+ #
3273
+ # If you want to clip other dtypes, consider writing a "when, then, otherwise"
3274
+ # expression. See {#when} for more information.
3275
+ #
3276
+ # @param min_val [Numeric]
3277
+ # Minimum value.
3278
+ # @param max_val [Numeric]
3279
+ # Maximum value.
3280
+ #
3281
+ # @return [Series]
3282
+ #
3283
+ # @example
3284
+ # s = Polars::Series.new("foo", [-50, 5, nil, 50])
3285
+ # s.clip(1, 10)
3286
+ # # =>
3287
+ # # shape: (4,)
3288
+ # # Series: 'foo' [i64]
3289
+ # # [
3290
+ # # 1
3291
+ # # 5
3292
+ # # null
3293
+ # # 10
3294
+ # # ]
3295
+ def clip(min_val, max_val)
3296
+ super
3297
+ end
3298
+
3299
+ # Clip (limit) the values in an array to a `min` boundary.
3300
+ #
3301
+ # Only works for numerical types.
3302
+ #
3303
+ # If you want to clip other dtypes, consider writing a "when, then, otherwise"
3304
+ # expression. See {#when} for more information.
3305
+ #
3306
+ # @param min_val [Numeric]
3307
+ # Minimum value.
3308
+ #
3309
+ # @return [Series]
3310
+ def clip_min(min_val)
3311
+ super
3312
+ end
3313
+
3314
+ # Clip (limit) the values in an array to a `max` boundary.
3315
+ #
3316
+ # Only works for numerical types.
3317
+ #
3318
+ # If you want to clip other dtypes, consider writing a "when, then, otherwise"
3319
+ # expression. See {#when} for more information.
3320
+ #
3321
+ # @param max_val [Numeric]
3322
+ # Maximum value.
3323
+ #
3324
+ # @return [Series]
3325
+ def clip_max(max_val)
3326
+ super
3327
+ end
3328
+
3329
+ # Reshape this Series to a flat Series or a Series of Lists.
3330
+ #
3331
+ # @param dims [Array]
3332
+ # Tuple of the dimension sizes. If a -1 is used in any of the dimensions, that
3333
+ # dimension is inferred.
3334
+ #
3335
+ # @return [Series]
3336
+ def reshape(dims)
3337
+ super
3338
+ end
3339
+
3340
+ # Shuffle the contents of this Series.
3341
+ #
3342
+ # @param seed [Integer, nil]
3343
+ # Seed for the random number generator.
3344
+ #
3345
+ # @return [Series]
3346
+ #
3347
+ # @example
3348
+ # s = Polars::Series.new("a", [1, 2, 3])
3349
+ # s.shuffle(seed: 1)
3350
+ # # =>
3351
+ # # shape: (3,)
3352
+ # # Series: 'a' [i64]
3353
+ # # [
3354
+ # # 2
3355
+ # # 1
3356
+ # # 3
3357
+ # # ]
3358
+ def shuffle(seed: nil)
3359
+ super
3360
+ end
3361
+
3362
+ # Exponentially-weighted moving average.
3363
+ #
3364
+ # @return [Series]
3365
+ def ewm_mean(
3366
+ com: nil,
3367
+ span: nil,
3368
+ half_life: nil,
3369
+ alpha: nil,
3370
+ adjust: true,
3371
+ min_periods: 1
3372
+ )
3373
+ super
3374
+ end
3375
+
3376
+ # Exponentially-weighted moving standard deviation.
3377
+ #
3378
+ # @return [Series]
3379
+ def ewm_std(
3380
+ com: nil,
3381
+ span: nil,
3382
+ half_life: nil,
3383
+ alpha: nil,
3384
+ adjust: true,
3385
+ bias: false,
3386
+ min_periods: 1
3387
+ )
3388
+ super
3389
+ end
3390
+
3391
+ # Exponentially-weighted moving variance.
3392
+ #
3393
+ # @return [Series]
3394
+ def ewm_var(
3395
+ com: nil,
3396
+ span: nil,
3397
+ half_life: nil,
3398
+ alpha: nil,
3399
+ adjust: true,
3400
+ bias: false,
3401
+ min_periods: 1
3402
+ )
3403
+ super
3404
+ end
3405
+
3406
+ # Extend the Series with given number of values.
3407
+ #
3408
+ # @param value [Object]
3409
+ # The value to extend the Series with. This value may be `nil` to fill with
3410
+ # nulls.
3411
+ # @param n [Integer]
3412
+ # The number of values to extend.
3413
+ #
3414
+ # @return [Series]
3415
+ #
3416
+ # @example
3417
+ # s = Polars::Series.new("a", [1, 2, 3])
3418
+ # s.extend_constant(99, 2)
3419
+ # # =>
3420
+ # # shape: (5,)
3421
+ # # Series: 'a' [i64]
3422
+ # # [
3423
+ # # 1
3424
+ # # 2
3425
+ # # 3
3426
+ # # 99
3427
+ # # 99
3428
+ # # ]
3429
+ def extend_constant(value, n)
3430
+ super
3431
+ end
3432
+
3433
+ # Flags the Series as sorted.
3434
+ #
3435
+ # Enables downstream code to user fast paths for sorted arrays.
3436
+ #
3437
+ # @param reverse [Boolean]
3438
+ # If the Series order is reversed, e.g. descending.
3439
+ #
3440
+ # @return [Series]
3441
+ #
3442
+ # @note
3443
+ # This can lead to incorrect results if this Series is not sorted!!
3444
+ # Use with care!
3445
+ #
3446
+ # @example
3447
+ # s = Polars::Series.new("a", [1, 2, 3])
3448
+ # s.set_sorted.max
3449
+ # # => 3
3450
+ def set_sorted(reverse: false)
3451
+ Utils.wrap_s(_s.set_sorted(reverse))
3452
+ end
3453
+
3454
+ # Create a new Series filled with values from the given index.
3455
+ #
3456
+ # @return [Series]
3457
+ def new_from_index(index, length)
3458
+ Utils.wrap_s(_s.new_from_index(index, length))
3459
+ end
3460
+
3461
+ # Shrink numeric columns to the minimal required datatype.
3462
+ #
3463
+ # Shrink to the dtype needed to fit the extrema of this Series.
3464
+ # This can be used to reduce memory pressure.
3465
+ #
3466
+ # @return [Series]
3467
+ def shrink_dtype
3468
+ super
3469
+ end
3470
+
3471
+ # Create an object namespace of all list related methods.
3472
+ #
3473
+ # @return [ListNameSpace]
3474
+ def arr
3475
+ ListNameSpace.new(self)
3476
+ end
3477
+
3478
+ # Create an object namespace of all categorical related methods.
3479
+ #
3480
+ # @return [CatNameSpace]
3481
+ def cat
3482
+ CatNameSpace.new(self)
3483
+ end
3484
+
3485
+ # Create an object namespace of all datetime related methods.
3486
+ #
3487
+ # @return [DateTimeNameSpace]
3488
+ def dt
3489
+ DateTimeNameSpace.new(self)
3490
+ end
3491
+
3492
+ # Create an object namespace of all string related methods.
3493
+ #
3494
+ # @return [StringNameSpace]
3495
+ def str
3496
+ StringNameSpace.new(self)
3497
+ end
3498
+
3499
+ # Create an object namespace of all struct related methods.
3500
+ #
3501
+ # @return [StructNameSpace]
3502
+ def struct
3503
+ StructNameSpace.new(self)
3504
+ end
3505
+
3506
+ private
3507
+
3508
+ def initialize_copy(other)
3509
+ super
3510
+ self._s = _s._clone
3511
+ end
3512
+
3513
+ def coerce(other)
3514
+ if other.is_a?(Numeric)
3515
+ # TODO improve
3516
+ series = to_frame.select(Polars.lit(other)).to_series
3517
+ [series, self]
3518
+ else
3519
+ raise TypeError, "#{self.class} can't be coerced into #{other.class}"
3520
+ end
3521
+ end
3522
+
3523
+ def _comp(other, op)
3524
+ if other.is_a?(Series)
3525
+ return Utils.wrap_s(_s.send(op, other._s))
3526
+ end
3527
+
3528
+ if dtype == Utf8
3529
+ raise Todo
3530
+ end
3531
+ Utils.wrap_s(_s.send("#{op}_#{DTYPE_TO_FFINAME.fetch(dtype)}", other))
3532
+ end
3533
+
3534
+ def _arithmetic(other, op)
3535
+ if other.is_a?(Expr)
3536
+ other = to_frame.select(other).to_series
3537
+ end
3538
+ if other.is_a?(Series)
3539
+ return Utils.wrap_s(_s.send(op, other._s))
3540
+ end
3541
+
3542
+ if other.is_a?(::Date) || other.is_a?(::DateTime) || other.is_a?(::Time) || other.is_a?(String)
3543
+ raise Todo
3544
+ end
3545
+ if other.is_a?(Float) && !is_float
3546
+ raise Todo
3547
+ end
3548
+
3549
+ Utils.wrap_s(_s.send("#{op}_#{DTYPE_TO_FFINAME.fetch(dtype)}", other))
3550
+ end
3551
+
3552
+ DTYPE_TO_FFINAME = {
3553
+ Int8 => "i8",
3554
+ Int16 => "i16",
3555
+ Int32 => "i32",
3556
+ Int64 => "i64",
3557
+ UInt8 => "u8",
3558
+ UInt16 => "u16",
3559
+ UInt32 => "u32",
3560
+ UInt64 => "u64",
3561
+ Float32 => "f32",
3562
+ Float64 => "f64",
3563
+ Boolean => "bool",
3564
+ Utf8 => "str",
3565
+ List => "list",
3566
+ Date => "date",
3567
+ Datetime => "datetime",
3568
+ Duration => "duration",
3569
+ Time => "time",
3570
+ Object => "object",
3571
+ Categorical => "categorical",
3572
+ Struct => "struct",
3573
+ Binary => "binary"
3574
+ }
3575
+
3576
+ def series_to_rbseries(name, values)
3577
+ # should not be in-place?
3578
+ values.rename(name, in_place: true)
3579
+ values._s
3580
+ end
3581
+
3582
+ def sequence_to_rbseries(name, values, dtype: nil, strict: true, dtype_if_empty: nil)
3583
+ ruby_dtype = nil
3584
+ nested_dtype = nil
3585
+
3586
+ if (values.nil? || values.empty?) && dtype.nil?
3587
+ if dtype_if_empty
3588
+ # if dtype for empty sequence could be guessed
3589
+ # (e.g comparisons between self and other)
3590
+ dtype = dtype_if_empty
3591
+ else
3592
+ # default to Float32 type
3593
+ dtype = :f32
3594
+ end
3595
+ end
3596
+
3597
+ rb_temporal_types = []
3598
+ rb_temporal_types << ::Date if defined?(::Date)
3599
+ rb_temporal_types << ::DateTime if defined?(::DateTime)
3600
+ rb_temporal_types << ::Time if defined?(::Time)
3601
+
3602
+ value = _get_first_non_none(values)
3603
+
3604
+ if !dtype.nil? && Utils.is_polars_dtype(dtype) && ruby_dtype.nil?
3605
+ constructor = polars_type_to_constructor(dtype)
3606
+ rbseries = constructor.call(name, values, strict)
3607
+ return rbseries
3608
+ else
3609
+ if ruby_dtype.nil?
3610
+ if value.nil?
3611
+ # generic default dtype
3612
+ ruby_dtype = Float
3613
+ else
3614
+ ruby_dtype = value.class
3615
+ end
3616
+ end
3617
+
3618
+ # temporal branch
3619
+ if rb_temporal_types.include?(ruby_dtype)
3620
+ # if dtype.nil?
3621
+ # dtype = rb_type_to_dtype(ruby_dtype)
3622
+ # elsif rb_temporal_types.include?(dtype)
3623
+ # dtype = rb_type_to_dtype(dtype)
3624
+ # end
3625
+
3626
+ if ruby_dtype == ::Date
3627
+ RbSeries.new_opt_date(name, values, strict)
3628
+ elsif ruby_dtype == ::Time
3629
+ RbSeries.new_opt_datetime(name, values, strict)
3630
+ elsif ruby_dtype == ::DateTime
3631
+ RbSeries.new_opt_datetime(name, values.map(&:to_time), strict)
3632
+ else
3633
+ raise Todo
3634
+ end
3635
+ elsif ruby_dtype == Array
3636
+ if nested_dtype.nil?
3637
+ nested_value = _get_first_non_none(value)
3638
+ nested_dtype = nested_value.nil? ? Float : nested_value.class
3639
+ end
3640
+
3641
+ if nested_dtype == Array
3642
+ raise Todo
3643
+ end
3644
+
3645
+ if value.is_a?(Array)
3646
+ count = 0
3647
+ equal_to_inner = true
3648
+ values.each do |lst|
3649
+ lst.each do |vl|
3650
+ equal_to_inner = vl.class == nested_dtype
3651
+ if !equal_to_inner || count > 50
3652
+ break
3653
+ end
3654
+ count += 1
3655
+ end
3656
+ end
3657
+ if equal_to_inner
3658
+ dtype = Utils.rb_type_to_dtype(nested_dtype)
3659
+ # TODO rescue and fallback to new_object
3660
+ return RbSeries.new_list(name, values, dtype)
3661
+ end
3662
+ end
3663
+
3664
+ RbSeries.new_object(name, values, strict)
3665
+ else
3666
+ constructor = rb_type_to_constructor(value.class)
3667
+ constructor.call(name, values, strict)
3668
+ end
3669
+ end
3670
+ end
3671
+
3672
+ POLARS_TYPE_TO_CONSTRUCTOR = {
3673
+ Float32 => RbSeries.method(:new_opt_f32),
3674
+ Float64 => RbSeries.method(:new_opt_f64),
3675
+ Int8 => RbSeries.method(:new_opt_i8),
3676
+ Int16 => RbSeries.method(:new_opt_i16),
3677
+ Int32 => RbSeries.method(:new_opt_i32),
3678
+ Int64 => RbSeries.method(:new_opt_i64),
3679
+ UInt8 => RbSeries.method(:new_opt_u8),
3680
+ UInt16 => RbSeries.method(:new_opt_u16),
3681
+ UInt32 => RbSeries.method(:new_opt_u32),
3682
+ UInt64 => RbSeries.method(:new_opt_u64),
3683
+ Boolean => RbSeries.method(:new_opt_bool),
3684
+ Utf8 => RbSeries.method(:new_str)
3685
+ }
3686
+
3687
+ SYM_TYPE_TO_CONSTRUCTOR = {
3688
+ f32: RbSeries.method(:new_opt_f32),
3689
+ f64: RbSeries.method(:new_opt_f64),
3690
+ i8: RbSeries.method(:new_opt_i8),
3691
+ i16: RbSeries.method(:new_opt_i16),
3692
+ i32: RbSeries.method(:new_opt_i32),
3693
+ i64: RbSeries.method(:new_opt_i64),
3694
+ u8: RbSeries.method(:new_opt_u8),
3695
+ u16: RbSeries.method(:new_opt_u16),
3696
+ u32: RbSeries.method(:new_opt_u32),
3697
+ u64: RbSeries.method(:new_opt_u64),
3698
+ bool: RbSeries.method(:new_opt_bool),
3699
+ str: RbSeries.method(:new_str)
3700
+ }
3701
+
3702
+ def polars_type_to_constructor(dtype)
3703
+ if dtype.is_a?(Class) && dtype < DataType
3704
+ POLARS_TYPE_TO_CONSTRUCTOR.fetch(dtype)
3705
+ else
3706
+ SYM_TYPE_TO_CONSTRUCTOR.fetch(dtype.to_sym)
3707
+ end
3708
+ rescue KeyError
3709
+ raise ArgumentError, "Cannot construct RbSeries for type #{dtype}."
3710
+ end
3711
+
3712
+ RB_TYPE_TO_CONSTRUCTOR = {
3713
+ Float => RbSeries.method(:new_opt_f64),
3714
+ Integer => RbSeries.method(:new_opt_i64),
3715
+ String => RbSeries.method(:new_str),
3716
+ TrueClass => RbSeries.method(:new_opt_bool),
3717
+ FalseClass => RbSeries.method(:new_opt_bool)
3718
+ }
3719
+
3720
+ def rb_type_to_constructor(dtype)
3721
+ RB_TYPE_TO_CONSTRUCTOR.fetch(dtype)
3722
+ rescue KeyError
3723
+ RbSeries.method(:new_object)
3724
+ end
3725
+
3726
+ def _get_first_non_none(values)
3727
+ values.find { |v| !v.nil? }
3728
+ end
3729
+ end
3730
+ end