polars-df 0.2.0-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
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