polars-df 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +3 -0
  3. data/CHANGELOG.md +9 -0
  4. data/Cargo.lock +74 -3
  5. data/Cargo.toml +3 -0
  6. data/README.md +1 -1
  7. data/ext/polars/Cargo.toml +18 -1
  8. data/ext/polars/src/conversion.rs +115 -2
  9. data/ext/polars/src/dataframe.rs +228 -11
  10. data/ext/polars/src/error.rs +4 -0
  11. data/ext/polars/src/lazy/dataframe.rs +5 -5
  12. data/ext/polars/src/lazy/dsl.rs +157 -2
  13. data/ext/polars/src/lib.rs +185 -10
  14. data/ext/polars/src/list_construction.rs +100 -0
  15. data/ext/polars/src/series.rs +217 -29
  16. data/ext/polars/src/set.rs +91 -0
  17. data/ext/polars/src/utils.rs +19 -0
  18. data/lib/polars/batched_csv_reader.rb +1 -0
  19. data/lib/polars/cat_expr.rb +39 -0
  20. data/lib/polars/cat_name_space.rb +54 -0
  21. data/lib/polars/data_frame.rb +2384 -140
  22. data/lib/polars/date_time_expr.rb +1282 -7
  23. data/lib/polars/date_time_name_space.rb +1484 -0
  24. data/lib/polars/exceptions.rb +20 -0
  25. data/lib/polars/expr.rb +4374 -53
  26. data/lib/polars/expr_dispatch.rb +22 -0
  27. data/lib/polars/functions.rb +219 -0
  28. data/lib/polars/group_by.rb +518 -0
  29. data/lib/polars/io.rb +421 -2
  30. data/lib/polars/lazy_frame.rb +1267 -69
  31. data/lib/polars/lazy_functions.rb +412 -24
  32. data/lib/polars/lazy_group_by.rb +80 -0
  33. data/lib/polars/list_expr.rb +507 -5
  34. data/lib/polars/list_name_space.rb +346 -0
  35. data/lib/polars/meta_expr.rb +21 -0
  36. data/lib/polars/series.rb +2256 -242
  37. data/lib/polars/slice.rb +104 -0
  38. data/lib/polars/string_expr.rb +847 -10
  39. data/lib/polars/string_name_space.rb +690 -0
  40. data/lib/polars/struct_expr.rb +73 -0
  41. data/lib/polars/struct_name_space.rb +64 -0
  42. data/lib/polars/utils.rb +71 -3
  43. data/lib/polars/version.rb +2 -1
  44. data/lib/polars/when.rb +1 -0
  45. data/lib/polars/when_then.rb +1 -0
  46. data/lib/polars.rb +12 -10
  47. metadata +15 -2
data/lib/polars/series.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  module Polars
2
2
  # A Series represents a single column in a polars DataFrame.
3
3
  class Series
4
- # @private
5
- attr_accessor :_s
4
+ include ExprDispatch
6
5
 
7
6
  # Create a new Series.
8
7
  #
@@ -48,6 +47,8 @@ module Polars
48
47
 
49
48
  if values.nil?
50
49
  self._s = sequence_to_rbseries(name, [], dtype: dtype, dtype_if_empty: dtype_if_empty)
50
+ elsif values.is_a?(Series)
51
+ self._s = series_to_rbseries(name, values)
51
52
  elsif values.is_a?(Range)
52
53
  self._s =
53
54
  Polars.arange(
@@ -130,6 +131,9 @@ module Polars
130
131
  #
131
132
  # @return [Series]
132
133
  def &(other)
134
+ if !other.is_a?(Series)
135
+ other = Series.new([other])
136
+ end
133
137
  Utils.wrap_s(_s.bitand(other._s))
134
138
  end
135
139
 
@@ -137,6 +141,9 @@ module Polars
137
141
  #
138
142
  # @return [Series]
139
143
  def |(other)
144
+ if !other.is_a?(Series)
145
+ other = Series.new([other])
146
+ end
140
147
  Utils.wrap_s(_s.bitor(other._s))
141
148
  end
142
149
 
@@ -144,53 +151,90 @@ module Polars
144
151
  #
145
152
  # @return [Series]
146
153
  def ^(other)
154
+ if !other.is_a?(Series)
155
+ other = Series.new([other])
156
+ end
147
157
  Utils.wrap_s(_s.bitxor(other._s))
148
158
  end
149
159
 
150
- # def ==(other)
151
- # end
160
+ # Equal.
161
+ #
162
+ # @return [Series]
163
+ def ==(other)
164
+ _comp(other, :eq)
165
+ end
152
166
 
153
- # def !=(other)
154
- # end
167
+ # Not equal.
168
+ #
169
+ # @return [Series]
170
+ def !=(other)
171
+ _comp(other, :neq)
172
+ end
155
173
 
156
- # def >(other)
157
- # end
174
+ # Greater than.
175
+ #
176
+ # @return [Series]
177
+ def >(other)
178
+ _comp(other, :gt)
179
+ end
158
180
 
159
- # def <(other)
160
- # end
181
+ # Less than.
182
+ #
183
+ # @return [Series]
184
+ def <(other)
185
+ _comp(other, :lt)
186
+ end
161
187
 
162
- # def >=(other)
163
- # end
188
+ # Greater than or equal.
189
+ #
190
+ # @return [Series]
191
+ def >=(other)
192
+ _comp(other, :gt_eq)
193
+ end
164
194
 
165
- # def <=(other)
166
- # end
195
+ # Less than or equal.
196
+ #
197
+ # @return [Series]
198
+ def <=(other)
199
+ _comp(other, :lt_eq)
200
+ end
167
201
 
168
202
  # Performs addition.
169
203
  #
170
204
  # @return [Series]
171
205
  def +(other)
172
- Utils. wrap_s(_s.add(other._s))
206
+ _arithmetic(other, :add)
173
207
  end
174
208
 
175
209
  # Performs subtraction.
176
210
  #
177
211
  # @return [Series]
178
212
  def -(other)
179
- Utils.wrap_s(_s.sub(other._s))
213
+ _arithmetic(other, :sub)
180
214
  end
181
215
 
182
216
  # Performs multiplication.
183
217
  #
184
218
  # @return [Series]
185
219
  def *(other)
186
- Utils.wrap_s(_s.mul(other._s))
220
+ _arithmetic(other, :mul)
187
221
  end
188
222
 
189
223
  # Performs division.
190
224
  #
191
225
  # @return [Series]
192
226
  def /(other)
193
- Utils.wrap_s(_s.div(other._s))
227
+ _arithmetic(other, :div)
228
+ end
229
+
230
+ # Returns the modulo.
231
+ #
232
+ # @return [Series]
233
+ def %(other)
234
+ if is_datelike
235
+ raise ArgumentError, "first cast to integer before applying modulo on datelike dtypes"
236
+ end
237
+ _arithmetic(other, :rem)
194
238
  end
195
239
 
196
240
  # Raises to the power of exponent.
@@ -203,18 +247,63 @@ module Polars
203
247
  to_frame.select(Polars.col(name).pow(power)).to_series
204
248
  end
205
249
 
206
- # def -@(other)
207
- # end
250
+ # Performs negation.
251
+ #
252
+ # @return [Series]
253
+ def -@
254
+ 0 - self
255
+ end
208
256
 
209
257
  # Returns elements of the Series.
210
258
  #
211
259
  # @return [Object]
212
260
  def [](item)
213
- _s.get_idx(item)
261
+ if item.is_a?(Integer)
262
+ return _s.get_idx(item)
263
+ end
264
+
265
+ if item.is_a?(Range)
266
+ return Slice.new(self).apply(item)
267
+ end
268
+
269
+ raise ArgumentError, "Cannot get item of type: #{item.class.name}"
214
270
  end
215
271
 
216
- # def []=(key, value)
217
- # end
272
+ # Sets an element of the Series.
273
+ #
274
+ # @return [Object]
275
+ def []=(key, value)
276
+ if value.is_a?(Array)
277
+ if is_numeric || is_datelike
278
+ set_at_idx(key, value)
279
+ return
280
+ end
281
+ raise ArgumentError, "cannot set Series of dtype: #{dtype} with list/tuple as value; use a scalar value"
282
+ end
283
+
284
+ if key.is_a?(Series)
285
+ if key.dtype == :bool
286
+ self._s = set(key, value)._s
287
+ elsif key.dtype == :u64
288
+ self._s = set_at_idx(key.cast(:u32), value)._s
289
+ elsif key.dtype == :u32
290
+ self._s = set_at_idx(key, value)._s
291
+ else
292
+ raise Todo
293
+ end
294
+ end
295
+
296
+ if key.is_a?(Array)
297
+ s = Utils.wrap_s(sequence_to_rbseries("", key, dtype: :u32))
298
+ self[s] = value
299
+ elsif key.is_a?(Integer)
300
+ # TODO fix
301
+ # self[[key]] = value
302
+ set_at_idx(key, value)
303
+ else
304
+ raise ArgumentError, "cannot use #{key} for indexing"
305
+ end
306
+ end
218
307
 
219
308
  # Return an estimation of the total (heap) allocated size of the Series.
220
309
  #
@@ -268,20 +357,43 @@ module Polars
268
357
  to_frame.select(Polars.col(name).all).to_series[0]
269
358
  end
270
359
 
271
- # def log
272
- # end
360
+ # Compute the logarithm to a given base.
361
+ #
362
+ # @param base [Float]
363
+ # Given base, defaults to `Math::E`.
364
+ #
365
+ # @return [Series]
366
+ def log(base = Math::E)
367
+ super
368
+ end
273
369
 
274
- # def log10
275
- # end
370
+ # Compute the base 10 logarithm of the input array, element-wise.
371
+ #
372
+ # @return [Series]
373
+ def log10
374
+ super
375
+ end
276
376
 
277
- # def exp
278
- # end
377
+ # Compute the exponential, element-wise.
378
+ #
379
+ # @return [Series]
380
+ def exp
381
+ super
382
+ end
279
383
 
280
- # def drop_nulls
281
- # end
384
+ # Create a new Series that copies data from this Series without null values.
385
+ #
386
+ # @return [Series]
387
+ def drop_nulls
388
+ super
389
+ end
282
390
 
283
- # def drop_nans
284
- # end
391
+ # Drop NaN values.
392
+ #
393
+ # @return [Series]
394
+ def drop_nans
395
+ super
396
+ end
285
397
 
286
398
  # Cast this Series to a DataFrame.
287
399
  #
@@ -290,8 +402,94 @@ module Polars
290
402
  Utils.wrap_df(RbDataFrame.new([_s]))
291
403
  end
292
404
 
293
- # def describe
294
- # end
405
+ # Quick summary statistics of a series.
406
+ #
407
+ # Series with mixed datatypes will return summary statistics for the datatype of
408
+ # the first value.
409
+ #
410
+ # @return [DataFrame]
411
+ #
412
+ # @example
413
+ # series_num = Polars::Series.new([1, 2, 3, 4, 5])
414
+ # series_num.describe
415
+ # # =>
416
+ # # shape: (6, 2)
417
+ # # ┌────────────┬──────────┐
418
+ # # │ statistic ┆ value │
419
+ # # │ --- ┆ --- │
420
+ # # │ str ┆ f64 │
421
+ # # ╞════════════╪══════════╡
422
+ # # │ min ┆ 1.0 │
423
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
424
+ # # │ max ┆ 5.0 │
425
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
426
+ # # │ null_count ┆ 0.0 │
427
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
428
+ # # │ mean ┆ 3.0 │
429
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
430
+ # # │ std ┆ 1.581139 │
431
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
432
+ # # │ count ┆ 5.0 │
433
+ # # └────────────┴──────────┘
434
+ #
435
+ # @example
436
+ # series_str = Polars::Series.new(["a", "a", nil, "b", "c"])
437
+ # series_str.describe
438
+ # # =>
439
+ # # shape: (3, 2)
440
+ # # ┌────────────┬───────┐
441
+ # # │ statistic ┆ value │
442
+ # # │ --- ┆ --- │
443
+ # # │ str ┆ i64 │
444
+ # # ╞════════════╪═══════╡
445
+ # # │ unique ┆ 4 │
446
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
447
+ # # │ null_count ┆ 1 │
448
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
449
+ # # │ count ┆ 5 │
450
+ # # └────────────┴───────┘
451
+ def describe
452
+ if len == 0
453
+ raise ArgumentError, "Series must contain at least one value"
454
+ elsif is_numeric
455
+ s = cast(:f64)
456
+ stats = {
457
+ "min" => s.min,
458
+ "max" => s.max,
459
+ "null_count" => s.null_count,
460
+ "mean" => s.mean,
461
+ "std" => s.std,
462
+ "count" => s.len
463
+ }
464
+ elsif is_boolean
465
+ stats = {
466
+ "sum" => sum,
467
+ "null_count" => null_count,
468
+ "count" => len
469
+ }
470
+ elsif is_utf8
471
+ stats = {
472
+ "unique" => unique.length,
473
+ "null_count" => null_count,
474
+ "count" => len
475
+ }
476
+ elsif is_datelike
477
+ # we coerce all to string, because a polars column
478
+ # only has a single dtype and dates: datetime and count: int don't match
479
+ stats = {
480
+ "min" => dt.min.to_s,
481
+ "max" => dt.max.to_s,
482
+ "null_count" => null_count.to_s,
483
+ "count" => len.to_s
484
+ }
485
+ else
486
+ raise TypeError, "This type is not supported"
487
+ end
488
+
489
+ Polars::DataFrame.new(
490
+ {"statistic" => stats.keys, "value" => stats.values}
491
+ )
492
+ end
295
493
 
296
494
  # Reduce this Series to the sum value.
297
495
  #
@@ -352,11 +550,19 @@ module Polars
352
550
  _s.max
353
551
  end
354
552
 
355
- # def nan_max
356
- # end
553
+ # Get maximum value, but propagate/poison encountered NaN values.
554
+ #
555
+ # @return [Object]
556
+ def nan_max
557
+ to_frame.select(Polars.col(name).nan_max)[0, 0]
558
+ end
357
559
 
358
- # def nan_min
359
- # end
560
+ # Get minimum value, but propagate/poison encountered NaN values.
561
+ #
562
+ # @return [Object]
563
+ def nan_min
564
+ to_frame.select(Polars.col(name).nan_min)[0, 0]
565
+ end
360
566
 
361
567
  # Get the standard deviation of this Series.
362
568
  #
@@ -478,14 +684,86 @@ module Polars
478
684
  Utils.wrap_df(_s.value_counts(sort))
479
685
  end
480
686
 
481
- # def unique_counts
482
- # end
687
+ # Return a count of the unique values in the order of appearance.
688
+ #
689
+ # @return [Series]
690
+ #
691
+ # @example
692
+ # s = Polars::Series.new("id", ["a", "b", "b", "c", "c", "c"])
693
+ # s.unique_counts
694
+ # # =>
695
+ # # shape: (3,)
696
+ # # Series: 'id' [u32]
697
+ # # [
698
+ # # 1
699
+ # # 2
700
+ # # 3
701
+ # # ]
702
+ def unique_counts
703
+ super
704
+ end
483
705
 
484
- # def entropy
485
- # end
706
+ # Computes the entropy.
707
+ #
708
+ # Uses the formula `-sum(pk * log(pk)` where `pk` are discrete probabilities.
709
+ #
710
+ # @param base [Float]
711
+ # Given base, defaults to `e`
712
+ # @param normalize [Boolean]
713
+ # Normalize pk if it doesn't sum to 1.
714
+ #
715
+ # @return [Float, nil]
716
+ #
717
+ # @example
718
+ # a = Polars::Series.new([0.99, 0.005, 0.005])
719
+ # a.entropy(normalize: true)
720
+ # # => 0.06293300616044681
721
+ #
722
+ # @example
723
+ # b = Polars::Series.new([0.65, 0.10, 0.25])
724
+ # b.entropy(normalize: true)
725
+ # # => 0.8568409950394724
726
+ def entropy(base: Math::E, normalize: false)
727
+ Polars.select(Polars.lit(self).entropy(base: base, normalize: normalize)).to_series[0]
728
+ end
486
729
 
487
- # def cumulative_eval
488
- # end
730
+ # Run an expression over a sliding window that increases `1` slot every iteration.
731
+ #
732
+ # @param expr [Expr]
733
+ # Expression to evaluate
734
+ # @param min_periods [Integer]
735
+ # Number of valid values there should be in the window before the expression
736
+ # is evaluated. valid values = `length - null_count`
737
+ # @param parallel [Boolean]
738
+ # Run in parallel. Don't do this in a groupby or another operation that
739
+ # already has much parallelization.
740
+ #
741
+ # @return [Series]
742
+ #
743
+ # @note
744
+ # This functionality is experimental and may change without it being considered a
745
+ # breaking change.
746
+ #
747
+ # @note
748
+ # This can be really slow as it can have `O(n^2)` complexity. Don't use this
749
+ # for operations that visit all elements.
750
+ #
751
+ # @example
752
+ # s = Polars::Series.new("values", [1, 2, 3, 4, 5])
753
+ # s.cumulative_eval(Polars.element.first - Polars.element.last ** 2)
754
+ # # =>
755
+ # # shape: (5,)
756
+ # # Series: 'values' [f64]
757
+ # # [
758
+ # # 0.0
759
+ # # -3.0
760
+ # # -8.0
761
+ # # -15.0
762
+ # # -24.0
763
+ # # ]
764
+ def cumulative_eval(expr, min_periods: 1, parallel: false)
765
+ super
766
+ end
489
767
 
490
768
  # Return a copy of the Series with a new alias/name.
491
769
  #
@@ -585,7 +863,7 @@ module Polars
585
863
  # # 6
586
864
  # # ]
587
865
  def cumsum(reverse: false)
588
- Utils.wrap_s(_s.cumsum(reverse))
866
+ super
589
867
  end
590
868
 
591
869
  # Get an array with the cumulative min computed at every element.
@@ -607,7 +885,7 @@ module Polars
607
885
  # # 1
608
886
  # # ]
609
887
  def cummin(reverse: false)
610
- Utils.wrap_s(_s.cummin(reverse))
888
+ super
611
889
  end
612
890
 
613
891
  # Get an array with the cumulative max computed at every element.
@@ -629,7 +907,7 @@ module Polars
629
907
  # # 5
630
908
  # # ]
631
909
  def cummax(reverse: false)
632
- Utils.wrap_s(_s.cummax(reverse))
910
+ super
633
911
  end
634
912
 
635
913
  # Get an array with the cumulative product computed at every element.
@@ -655,7 +933,7 @@ module Polars
655
933
  # # 6
656
934
  # # ]
657
935
  def cumprod(reverse: false)
658
- Utils.wrap_s(_s.cumprod(reverse))
936
+ super
659
937
  end
660
938
 
661
939
  # Get the first `n` rows.
@@ -702,8 +980,7 @@ module Polars
702
980
  # # 3
703
981
  # # ]
704
982
  def slice(offset, length = nil)
705
- length = len if length.nil?
706
- Utils.wrap_s(_s.slice(offset, length))
983
+ super
707
984
  end
708
985
 
709
986
  # Append a Series to this one.
@@ -835,8 +1112,23 @@ module Polars
835
1112
  to_frame.select(Utils.col(name).tail(n)).to_series
836
1113
  end
837
1114
 
838
- # def take_every
839
- # end
1115
+ # Take every nth value in the Series and return as new Series.
1116
+ #
1117
+ # @return [Series]
1118
+ #
1119
+ # @example
1120
+ # s = Polars::Series.new("a", [1, 2, 3, 4])
1121
+ # s.take_every(2)
1122
+ # # =>
1123
+ # # shape: (2,)
1124
+ # # Series: 'a' [i64]
1125
+ # # [
1126
+ # # 1
1127
+ # # 3
1128
+ # # ]
1129
+ def take_every(n)
1130
+ super
1131
+ end
840
1132
 
841
1133
  # Sort this Series.
842
1134
  #
@@ -878,17 +1170,78 @@ module Polars
878
1170
  end
879
1171
  end
880
1172
 
881
- # def top_k
882
- # end
1173
+ # Return the `k` largest elements.
1174
+ #
1175
+ # If `reverse: true`, the smallest elements will be given.
1176
+ #
1177
+ # @param k [Integer]
1178
+ # Number of elements to return.
1179
+ # @param reverse [Boolean]
1180
+ # Return the smallest elements.
1181
+ #
1182
+ # @return [Boolean]
1183
+ def top_k(k: 5, reverse: false)
1184
+ super
1185
+ end
883
1186
 
884
- # def arg_sort
885
- # end
1187
+ # Get the index values that would sort this Series.
1188
+ #
1189
+ # @param reverse [Boolean]
1190
+ # Sort in reverse (descending) order.
1191
+ # @param nulls_last [Boolean]
1192
+ # Place null values last instead of first.
1193
+ #
1194
+ # @return [Series]
1195
+ #
1196
+ # @example
1197
+ # s = Polars::Series.new("a", [5, 3, 4, 1, 2])
1198
+ # s.arg_sort
1199
+ # # =>
1200
+ # # shape: (5,)
1201
+ # # Series: 'a' [u32]
1202
+ # # [
1203
+ # # 3
1204
+ # # 4
1205
+ # # 1
1206
+ # # 2
1207
+ # # 0
1208
+ # # ]
1209
+ def arg_sort(reverse: false, nulls_last: false)
1210
+ super
1211
+ end
886
1212
 
887
- # def argsort
888
- # end
1213
+ # Get the index values that would sort this Series.
1214
+ #
1215
+ # Alias for {#arg_sort}.
1216
+ #
1217
+ # @param reverse [Boolean]
1218
+ # Sort in reverse (descending) order.
1219
+ # @param nulls_last [Boolean]
1220
+ # Place null values last instead of first.
1221
+ #
1222
+ # @return [Series]
1223
+ def argsort(reverse: false, nulls_last: false)
1224
+ super
1225
+ end
889
1226
 
890
- # def arg_unique
891
- # end
1227
+ # Get unique index as Series.
1228
+ #
1229
+ # @return [Series]
1230
+ #
1231
+ # @example
1232
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1233
+ # s.arg_unique
1234
+ # # =>
1235
+ # # shape: (3,)
1236
+ # # Series: 'a' [u32]
1237
+ # # [
1238
+ # # 0
1239
+ # # 1
1240
+ # # 3
1241
+ # # ]
1242
+ def arg_unique
1243
+ super
1244
+ end
892
1245
 
893
1246
  # Get the index of the minimal value.
894
1247
  #
@@ -914,14 +1267,58 @@ module Polars
914
1267
  _s.arg_max
915
1268
  end
916
1269
 
917
- # def search_sorted
918
- # end
1270
+ # Find indices where elements should be inserted to maintain order.
1271
+ #
1272
+ # @param element [Object]
1273
+ # Expression or scalar value.
1274
+ #
1275
+ # @return [Integer]
1276
+ def search_sorted(element)
1277
+ Polars.select(Polars.lit(self).search_sorted(element))[0, 0]
1278
+ end
919
1279
 
920
- # def unique
921
- # end
1280
+ # Get unique elements in series.
1281
+ #
1282
+ # @param maintain_order [Boolean]
1283
+ # Maintain order of data. This requires more work.
1284
+ #
1285
+ # @return [Series]
1286
+ #
1287
+ # @example
1288
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1289
+ # s.unique.sort
1290
+ # # =>
1291
+ # # shape: (3,)
1292
+ # # Series: 'a' [i64]
1293
+ # # [
1294
+ # # 1
1295
+ # # 2
1296
+ # # 3
1297
+ # # ]
1298
+ def unique(maintain_order: false)
1299
+ super
1300
+ end
922
1301
 
923
- # def take
924
- # end
1302
+ # Take values by index.
1303
+ #
1304
+ # @param indices [Array]
1305
+ # Index location used for selection.
1306
+ #
1307
+ # @return [Series]
1308
+ #
1309
+ # @example
1310
+ # s = Polars::Series.new("a", [1, 2, 3, 4])
1311
+ # s.take([1, 3])
1312
+ # # =>
1313
+ # # shape: (2,)
1314
+ # # Series: 'a' [i64]
1315
+ # # [
1316
+ # # 2
1317
+ # # 4
1318
+ # # ]
1319
+ def take(indices)
1320
+ to_frame.select(Polars.col(name).take(indices)).to_series
1321
+ end
925
1322
 
926
1323
  # Count the null values in this Series.
927
1324
  #
@@ -930,7 +1327,7 @@ module Polars
930
1327
  _s.null_count
931
1328
  end
932
1329
 
933
- # Return True if the Series has a validity bitmask.
1330
+ # Return `true` if the Series has a validity bitmask.
934
1331
  #
935
1332
  # If there is none, it means that there are no null values.
936
1333
  # Use this to swiftly assert a Series does not have null values.
@@ -953,41 +1350,263 @@ module Polars
953
1350
  end
954
1351
  alias_method :empty?, :is_empty
955
1352
 
956
- # def is_null
957
- # end
958
-
959
- # def is_not_null
960
- # end
961
-
962
- # def is_finite
963
- # end
964
-
965
- # def is_infinite
966
- # end
1353
+ # Returns a boolean Series indicating which values are null.
1354
+ #
1355
+ # @return [Series]
1356
+ #
1357
+ # @example
1358
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, nil])
1359
+ # s.is_null
1360
+ # # =>
1361
+ # # shape: (4,)
1362
+ # # Series: 'a' [bool]
1363
+ # # [
1364
+ # # false
1365
+ # # false
1366
+ # # false
1367
+ # # true
1368
+ # # ]
1369
+ def is_null
1370
+ super
1371
+ end
967
1372
 
968
- # def is_nan
969
- # end
1373
+ # Returns a boolean Series indicating which values are not null.
1374
+ #
1375
+ # @return [Series]
1376
+ #
1377
+ # @example
1378
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, nil])
1379
+ # s.is_not_null
1380
+ # # =>
1381
+ # # shape: (4,)
1382
+ # # Series: 'a' [bool]
1383
+ # # [
1384
+ # # true
1385
+ # # true
1386
+ # # true
1387
+ # # false
1388
+ # # ]
1389
+ def is_not_null
1390
+ super
1391
+ end
970
1392
 
971
- # def is_not_nan
972
- # end
1393
+ # Returns a boolean Series indicating which values are finite.
1394
+ #
1395
+ # @return [Series]
1396
+ #
1397
+ # @example
1398
+ # s = Polars::Series.new("a", [1.0, 2.0, Float::INFINITY])
1399
+ # s.is_finite
1400
+ # # =>
1401
+ # # shape: (3,)
1402
+ # # Series: 'a' [bool]
1403
+ # # [
1404
+ # # true
1405
+ # # true
1406
+ # # false
1407
+ # # ]
1408
+ def is_finite
1409
+ super
1410
+ end
973
1411
 
974
- # def is_in
975
- # end
1412
+ # Returns a boolean Series indicating which values are infinite.
1413
+ #
1414
+ # @return [Series]
1415
+ #
1416
+ # @example
1417
+ # s = Polars::Series.new("a", [1.0, 2.0, Float::INFINITY])
1418
+ # s.is_infinite
1419
+ # # =>
1420
+ # # shape: (3,)
1421
+ # # Series: 'a' [bool]
1422
+ # # [
1423
+ # # false
1424
+ # # false
1425
+ # # true
1426
+ # # ]
1427
+ def is_infinite
1428
+ super
1429
+ end
976
1430
 
977
- # def arg_true
978
- # end
1431
+ # Returns a boolean Series indicating which values are NaN.
1432
+ #
1433
+ # @return [Series]
1434
+ #
1435
+ # @example
1436
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, Float::NAN])
1437
+ # s.is_nan
1438
+ # # =>
1439
+ # # shape: (4,)
1440
+ # # Series: 'a' [bool]
1441
+ # # [
1442
+ # # false
1443
+ # # false
1444
+ # # false
1445
+ # # true
1446
+ # # ]
1447
+ def is_nan
1448
+ super
1449
+ end
979
1450
 
980
- # def is_unique
981
- # end
1451
+ # Returns a boolean Series indicating which values are not NaN.
1452
+ #
1453
+ # @return [Series]
1454
+ #
1455
+ # @example
1456
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, Float::NAN])
1457
+ # s.is_not_nan
1458
+ # # =>
1459
+ # # shape: (4,)
1460
+ # # Series: 'a' [bool]
1461
+ # # [
1462
+ # # true
1463
+ # # true
1464
+ # # true
1465
+ # # false
1466
+ # # ]
1467
+ def is_not_nan
1468
+ super
1469
+ end
982
1470
 
983
- # def is_first
984
- # end
1471
+ # Check if elements of this Series are in the other Series.
1472
+ #
1473
+ # @return [Series]
1474
+ #
1475
+ # @example
1476
+ # s = Polars::Series.new("a", [1, 2, 3])
1477
+ # s2 = Polars::Series.new("b", [2, 4])
1478
+ # s2.is_in(s)
1479
+ # # =>
1480
+ # # shape: (2,)
1481
+ # # Series: 'b' [bool]
1482
+ # # [
1483
+ # # true
1484
+ # # false
1485
+ # # ]
1486
+ #
1487
+ # @example
1488
+ # sets = Polars::Series.new("sets", [[1, 2, 3], [1, 2], [9, 10]])
1489
+ # # =>
1490
+ # # shape: (3,)
1491
+ # # Series: 'sets' [list]
1492
+ # # [
1493
+ # # [1, 2, 3]
1494
+ # # [1, 2]
1495
+ # # [9, 10]
1496
+ # # ]
1497
+ #
1498
+ # @example
1499
+ # optional_members = Polars::Series.new("optional_members", [1, 2, 3])
1500
+ # # =>
1501
+ # # shape: (3,)
1502
+ # # Series: 'optional_members' [i64]
1503
+ # # [
1504
+ # # 1
1505
+ # # 2
1506
+ # # 3
1507
+ # # ]
1508
+ #
1509
+ # @example
1510
+ # optional_members.is_in(sets)
1511
+ # # =>
1512
+ # # shape: (3,)
1513
+ # # Series: 'optional_members' [bool]
1514
+ # # [
1515
+ # # true
1516
+ # # true
1517
+ # # false
1518
+ # # ]
1519
+ def is_in(other)
1520
+ super
1521
+ end
985
1522
 
986
- # def is_duplicated
987
- # end
1523
+ # Get index values where Boolean Series evaluate `true`.
1524
+ #
1525
+ # @return [Series]
1526
+ #
1527
+ # @example
1528
+ # s = Polars::Series.new("a", [1, 2, 3])
1529
+ # (s == 2).arg_true
1530
+ # # =>
1531
+ # # shape: (1,)
1532
+ # # Series: 'a' [u32]
1533
+ # # [
1534
+ # # 1
1535
+ # # ]
1536
+ def arg_true
1537
+ Polars.arg_where(self, eager: true)
1538
+ end
988
1539
 
989
- # def explode
990
- # end
1540
+ # Get mask of all unique values.
1541
+ #
1542
+ # @return [Series]
1543
+ #
1544
+ # @example
1545
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1546
+ # s.is_unique
1547
+ # # =>
1548
+ # # shape: (4,)
1549
+ # # Series: 'a' [bool]
1550
+ # # [
1551
+ # # true
1552
+ # # false
1553
+ # # false
1554
+ # # true
1555
+ # # ]
1556
+ def is_unique
1557
+ super
1558
+ end
1559
+
1560
+ # Get a mask of the first unique value.
1561
+ #
1562
+ # @return [Series]
1563
+ def is_first
1564
+ super
1565
+ end
1566
+
1567
+ # Get mask of all duplicated values.
1568
+ #
1569
+ # @return [Series]
1570
+ #
1571
+ # @example
1572
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1573
+ # s.is_duplicated
1574
+ # # =>
1575
+ # # shape: (4,)
1576
+ # # Series: 'a' [bool]
1577
+ # # [
1578
+ # # false
1579
+ # # true
1580
+ # # true
1581
+ # # false
1582
+ # # ]
1583
+ def is_duplicated
1584
+ super
1585
+ end
1586
+
1587
+ # Explode a list or utf8 Series.
1588
+ #
1589
+ # This means that every item is expanded to a new row.
1590
+ #
1591
+ # @return [Series]
1592
+ #
1593
+ # @example
1594
+ # s = Polars::Series.new("a", [[1, 2], [3, 4], [9, 10]])
1595
+ # s.explode
1596
+ # # =>
1597
+ # # shape: (6,)
1598
+ # # Series: 'a' [i64]
1599
+ # # [
1600
+ # # 1
1601
+ # # 2
1602
+ # # 3
1603
+ # # 4
1604
+ # # 9
1605
+ # # 10
1606
+ # # ]
1607
+ def explode
1608
+ super
1609
+ end
991
1610
 
992
1611
  # Check if series is equal with another Series.
993
1612
  #
@@ -1025,8 +1644,29 @@ module Polars
1025
1644
  end
1026
1645
  alias_method :length, :len
1027
1646
 
1028
- # def cast
1029
- # end
1647
+ # Cast between data types.
1648
+ #
1649
+ # @param dtype [Symbol]
1650
+ # DataType to cast to
1651
+ # @param strict [Boolean]
1652
+ # Throw an error if a cast could not be done for instance due to an overflow
1653
+ #
1654
+ # @return [Series]
1655
+ #
1656
+ # @example
1657
+ # s = Polars::Series.new("a", [true, false, true])
1658
+ # s.cast(:u32)
1659
+ # # =>
1660
+ # # shape: (3,)
1661
+ # # Series: 'a' [u32]
1662
+ # # [
1663
+ # # 1
1664
+ # # 0
1665
+ # # 1
1666
+ # # ]
1667
+ def cast(dtype, strict: true)
1668
+ super
1669
+ end
1030
1670
 
1031
1671
  # def to_physical
1032
1672
  # end
@@ -1054,8 +1694,24 @@ module Polars
1054
1694
  in_place ? self : Utils.wrap_s(opt_s)
1055
1695
  end
1056
1696
 
1057
- # def reverse
1058
- # end
1697
+ # Return Series in reverse order.
1698
+ #
1699
+ # @return [Series]
1700
+ #
1701
+ # @example
1702
+ # s = Polars::Series.new("a", [1, 2, 3], dtype: :i8)
1703
+ # s.reverse
1704
+ # # =>
1705
+ # # shape: (3,)
1706
+ # # Series: 'a' [i8]
1707
+ # # [
1708
+ # # 3
1709
+ # # 2
1710
+ # # 1
1711
+ # # ]
1712
+ def reverse
1713
+ super
1714
+ end
1059
1715
 
1060
1716
  # Check if this Series datatype is numeric.
1061
1717
  #
@@ -1132,52 +1788,176 @@ module Polars
1132
1788
  # def set
1133
1789
  # end
1134
1790
 
1135
- # def set_at_idx
1136
- # end
1137
-
1138
- # def cleared
1139
- # end
1140
-
1141
- # clone handled by initialize_copy
1142
-
1143
- # def fill_nan
1144
- # end
1145
-
1146
- # def fill_null
1147
- # end
1148
-
1149
- # Rounds down to the nearest integer value.
1791
+ # Set values at the index locations.
1150
1792
  #
1151
- # Only works on floating point Series.
1793
+ # @param idx [Object]
1794
+ # Integers representing the index locations.
1795
+ # @param value [Object]
1796
+ # Replacement values.
1152
1797
  #
1153
1798
  # @return [Series]
1154
1799
  #
1155
1800
  # @example
1156
- # s = Polars::Series.new("a", [1.12345, 2.56789, 3.901234])
1157
- # s.floor
1801
+ # s = Polars::Series.new("a", [1, 2, 3])
1802
+ # s.set_at_idx(1, 10)
1158
1803
  # # =>
1159
1804
  # # shape: (3,)
1160
- # # Series: 'a' [f64]
1805
+ # # Series: 'a' [i64]
1161
1806
  # # [
1162
- # # 1.0
1163
- # # 2.0
1164
- # # 3.0
1807
+ # # 1
1808
+ # # 10
1809
+ # # 3
1165
1810
  # # ]
1166
- def floor
1167
- Utils.wrap_s(_s.floor)
1811
+ def set_at_idx(idx, value)
1812
+ if idx.is_a?(Integer)
1813
+ idx = [idx]
1814
+ end
1815
+ if idx.length == 0
1816
+ return self
1817
+ end
1818
+
1819
+ idx = Series.new("", idx)
1820
+ if value.is_a?(Integer) || value.is_a?(Float) || Utils.bool?(value) || value.is_a?(String) || value.nil?
1821
+ value = Series.new("", [value])
1822
+
1823
+ # if we need to set more than a single value, we extend it
1824
+ if idx.length > 0
1825
+ value = value.extend_constant(value[0], idx.length - 1)
1826
+ end
1827
+ elsif !value.is_a?(Series)
1828
+ value = Series.new("", value)
1829
+ end
1830
+ _s.set_at_idx(idx._s, value._s)
1831
+ self
1168
1832
  end
1169
1833
 
1170
- # Rounds up to the nearest integer value.
1834
+ # Create an empty copy of the current Series.
1171
1835
  #
1172
- # Only works on floating point Series.
1836
+ # The copy has identical name/dtype but no data.
1173
1837
  #
1174
1838
  # @return [Series]
1175
1839
  #
1176
1840
  # @example
1177
- # s = Polars::Series.new("a", [1.12345, 2.56789, 3.901234])
1178
- # s.ceil
1841
+ # s = Polars::Series.new("a", [nil, true, false])
1842
+ # s.cleared
1179
1843
  # # =>
1180
- # # shape: (3,)
1844
+ # # shape: (0,)
1845
+ # # Series: 'a' [bool]
1846
+ # # [
1847
+ # # ]
1848
+ def cleared
1849
+ len > 0 ? limit(0) : clone
1850
+ end
1851
+
1852
+ # clone handled by initialize_copy
1853
+
1854
+ # Fill floating point NaN value with a fill value.
1855
+ #
1856
+ # @param fill_value [Object]
1857
+ # Value used to fill nan values.
1858
+ #
1859
+ # @return [Series]
1860
+ #
1861
+ # @example
1862
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, Float::NAN])
1863
+ # s.fill_nan(0)
1864
+ # # =>
1865
+ # # shape: (4,)
1866
+ # # Series: 'a' [f64]
1867
+ # # [
1868
+ # # 1.0
1869
+ # # 2.0
1870
+ # # 3.0
1871
+ # # 0.0
1872
+ # # ]
1873
+ def fill_nan(fill_value)
1874
+ super
1875
+ end
1876
+
1877
+ # Fill null values using the specified value or strategy.
1878
+ #
1879
+ # @param value [Object]
1880
+ # Value used to fill null values.
1881
+ # @param strategy [nil, "forward", "backward", "min", "max", "mean", "zero", "one"]
1882
+ # Strategy used to fill null values.
1883
+ # @param limit
1884
+ # Number of consecutive null values to fill when using the "forward" or
1885
+ # "backward" strategy.
1886
+ #
1887
+ # @return [Series]
1888
+ #
1889
+ # @example
1890
+ # s = Polars::Series.new("a", [1, 2, 3, nil])
1891
+ # s.fill_null(strategy: "forward")
1892
+ # # =>
1893
+ # # shape: (4,)
1894
+ # # Series: 'a' [i64]
1895
+ # # [
1896
+ # # 1
1897
+ # # 2
1898
+ # # 3
1899
+ # # 3
1900
+ # # ]
1901
+ #
1902
+ # @example
1903
+ # s.fill_null(strategy: "min")
1904
+ # # =>
1905
+ # # shape: (4,)
1906
+ # # Series: 'a' [i64]
1907
+ # # [
1908
+ # # 1
1909
+ # # 2
1910
+ # # 3
1911
+ # # 1
1912
+ # # ]
1913
+ #
1914
+ # @example
1915
+ # s = Polars::Series.new("b", ["x", nil, "z"])
1916
+ # s.fill_null(Polars.lit(""))
1917
+ # # =>
1918
+ # # shape: (3,)
1919
+ # # Series: 'b' [str]
1920
+ # # [
1921
+ # # "x"
1922
+ # # ""
1923
+ # # "z"
1924
+ # # ]
1925
+ def fill_null(value = nil, strategy: nil, limit: nil)
1926
+ super
1927
+ end
1928
+
1929
+ # Rounds down to the nearest integer value.
1930
+ #
1931
+ # Only works on floating point Series.
1932
+ #
1933
+ # @return [Series]
1934
+ #
1935
+ # @example
1936
+ # s = Polars::Series.new("a", [1.12345, 2.56789, 3.901234])
1937
+ # s.floor
1938
+ # # =>
1939
+ # # shape: (3,)
1940
+ # # Series: 'a' [f64]
1941
+ # # [
1942
+ # # 1.0
1943
+ # # 2.0
1944
+ # # 3.0
1945
+ # # ]
1946
+ def floor
1947
+ Utils.wrap_s(_s.floor)
1948
+ end
1949
+
1950
+ # Rounds up to the nearest integer value.
1951
+ #
1952
+ # Only works on floating point Series.
1953
+ #
1954
+ # @return [Series]
1955
+ #
1956
+ # @example
1957
+ # s = Polars::Series.new("a", [1.12345, 2.56789, 3.901234])
1958
+ # s.ceil
1959
+ # # =>
1960
+ # # shape: (3,)
1181
1961
  # # Series: 'a' [f64]
1182
1962
  # # [
1183
1963
  # # 2.0
@@ -1185,7 +1965,7 @@ module Polars
1185
1965
  # # 4.0
1186
1966
  # # ]
1187
1967
  def ceil
1188
- Utils.wrap_s(_s.ceil)
1968
+ super
1189
1969
  end
1190
1970
 
1191
1971
  # Round underlying floating point data by `decimals` digits.
@@ -1207,98 +1987,900 @@ module Polars
1207
1987
  # # 3.9
1208
1988
  # # ]
1209
1989
  def round(decimals = 0)
1210
- Utils.wrap_s(_s.round(decimals))
1990
+ super
1211
1991
  end
1212
1992
 
1213
- # def dot
1214
- # end
1993
+ # Compute the dot/inner product between two Series.
1994
+ #
1995
+ # @param other [Object]
1996
+ # Series (or array) to compute dot product with.
1997
+ #
1998
+ # @return [Numeric]
1999
+ #
2000
+ # @example
2001
+ # s = Polars::Series.new("a", [1, 2, 3])
2002
+ # s2 = Polars::Series.new("b", [4.0, 5.0, 6.0])
2003
+ # s.dot(s2)
2004
+ # # => 32.0
2005
+ def dot(other)
2006
+ if !other.is_a?(Series)
2007
+ other = Series.new(other)
2008
+ end
2009
+ if len != other.len
2010
+ n, m = len, other.len
2011
+ raise ArgumentError, "Series length mismatch: expected #{n}, found #{m}"
2012
+ end
2013
+ _s.dot(other._s)
2014
+ end
1215
2015
 
1216
- # def mode
1217
- # end
2016
+ # Compute the most occurring value(s).
2017
+ #
2018
+ # Can return multiple Values.
2019
+ #
2020
+ # @return [Series]
2021
+ #
2022
+ # @example
2023
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
2024
+ # s.mode
2025
+ # # =>
2026
+ # # shape: (1,)
2027
+ # # Series: 'a' [i64]
2028
+ # # [
2029
+ # # 2
2030
+ # # ]
2031
+ def mode
2032
+ super
2033
+ end
1218
2034
 
1219
- # def sign
1220
- # end
2035
+ # Compute the element-wise indication of the sign.
2036
+ #
2037
+ # @return [Series]
2038
+ #
2039
+ # @example
2040
+ # s = Polars::Series.new("a", [-9.0, -0.0, 0.0, 4.0, nil])
2041
+ # s.sign
2042
+ # # =>
2043
+ # # shape: (5,)
2044
+ # # Series: 'a' [i64]
2045
+ # # [
2046
+ # # -1
2047
+ # # 0
2048
+ # # 0
2049
+ # # 1
2050
+ # # null
2051
+ # # ]
2052
+ def sign
2053
+ super
2054
+ end
1221
2055
 
1222
- # def sin
1223
- # end
2056
+ # Compute the element-wise value for the sine.
2057
+ #
2058
+ # @return [Series]
2059
+ #
2060
+ # @example
2061
+ # s = Polars::Series.new("a", [0.0, Math::PI / 2.0, Math::PI])
2062
+ # s.sin
2063
+ # # =>
2064
+ # # shape: (3,)
2065
+ # # Series: 'a' [f64]
2066
+ # # [
2067
+ # # 0.0
2068
+ # # 1.0
2069
+ # # 1.2246e-16
2070
+ # # ]
2071
+ def sin
2072
+ super
2073
+ end
1224
2074
 
1225
- # def cos
1226
- # end
2075
+ # Compute the element-wise value for the cosine.
2076
+ #
2077
+ # @return [Series]
2078
+ #
2079
+ # @example
2080
+ # s = Polars::Series.new("a", [0.0, Math::PI / 2.0, Math::PI])
2081
+ # s.cos
2082
+ # # =>
2083
+ # # shape: (3,)
2084
+ # # Series: 'a' [f64]
2085
+ # # [
2086
+ # # 1.0
2087
+ # # 6.1232e-17
2088
+ # # -1.0
2089
+ # # ]
2090
+ def cos
2091
+ super
2092
+ end
1227
2093
 
1228
- # def tan
1229
- # end
2094
+ # Compute the element-wise value for the tangent.
2095
+ #
2096
+ # @return [Series]
2097
+ #
2098
+ # @example
2099
+ # s = Polars::Series.new("a", [0.0, Math::PI / 2.0, Math::PI])
2100
+ # s.tan
2101
+ # # =>
2102
+ # # shape: (3,)
2103
+ # # Series: 'a' [f64]
2104
+ # # [
2105
+ # # 0.0
2106
+ # # 1.6331e16
2107
+ # # -1.2246e-16
2108
+ # # ]
2109
+ def tan
2110
+ super
2111
+ end
1230
2112
 
1231
- # def arcsin
1232
- # end
2113
+ # Compute the element-wise value for the inverse sine.
2114
+ #
2115
+ # @return [Series]
2116
+ #
2117
+ # @example
2118
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2119
+ # s.arcsin
2120
+ # # =>
2121
+ # # shape: (3,)
2122
+ # # Series: 'a' [f64]
2123
+ # # [
2124
+ # # 1.570796
2125
+ # # 0.0
2126
+ # # -1.570796
2127
+ # # ]
2128
+ def arcsin
2129
+ super
2130
+ end
1233
2131
 
1234
- # def arccos
1235
- # end
2132
+ # Compute the element-wise value for the inverse cosine.
2133
+ #
2134
+ # @return [Series]
2135
+ #
2136
+ # @example
2137
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2138
+ # s.arccos
2139
+ # # =>
2140
+ # # shape: (3,)
2141
+ # # Series: 'a' [f64]
2142
+ # # [
2143
+ # # 0.0
2144
+ # # 1.570796
2145
+ # # 3.141593
2146
+ # # ]
2147
+ def arccos
2148
+ super
2149
+ end
1236
2150
 
1237
- # def arctan
1238
- # end
2151
+ # Compute the element-wise value for the inverse tangent.
2152
+ #
2153
+ # @return [Series]
2154
+ #
2155
+ # @example
2156
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2157
+ # s.arctan
2158
+ # # =>
2159
+ # # shape: (3,)
2160
+ # # Series: 'a' [f64]
2161
+ # # [
2162
+ # # 0.785398
2163
+ # # 0.0
2164
+ # # -0.785398
2165
+ # # ]
2166
+ def arctan
2167
+ super
2168
+ end
1239
2169
 
1240
- # def arcsinh
1241
- # end
2170
+ # Compute the element-wise value for the inverse hyperbolic sine.
2171
+ #
2172
+ # @return [Series]
2173
+ #
2174
+ # @example
2175
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2176
+ # s.arcsinh
2177
+ # # =>
2178
+ # # shape: (3,)
2179
+ # # Series: 'a' [f64]
2180
+ # # [
2181
+ # # 0.881374
2182
+ # # 0.0
2183
+ # # -0.881374
2184
+ # # ]
2185
+ def arcsinh
2186
+ super
2187
+ end
1242
2188
 
1243
- # def arccosh
1244
- # end
2189
+ # Compute the element-wise value for the inverse hyperbolic cosine.
2190
+ #
2191
+ # @return [Series]
2192
+ #
2193
+ # @example
2194
+ # s = Polars::Series.new("a", [5.0, 1.0, 0.0, -1.0])
2195
+ # s.arccosh
2196
+ # # =>
2197
+ # # shape: (4,)
2198
+ # # Series: 'a' [f64]
2199
+ # # [
2200
+ # # 2.292432
2201
+ # # 0.0
2202
+ # # NaN
2203
+ # # NaN
2204
+ # # ]
2205
+ def arccosh
2206
+ super
2207
+ end
1245
2208
 
1246
- # def arctanh
1247
- # end
2209
+ # Compute the element-wise value for the inverse hyperbolic tangent.
2210
+ #
2211
+ # @return [Series]
2212
+ #
2213
+ # @example
2214
+ # s = Polars::Series.new("a", [2.0, 1.0, 0.5, 0.0, -0.5, -1.0, -1.1])
2215
+ # s.arctanh
2216
+ # # =>
2217
+ # # shape: (7,)
2218
+ # # Series: 'a' [f64]
2219
+ # # [
2220
+ # # NaN
2221
+ # # inf
2222
+ # # 0.549306
2223
+ # # 0.0
2224
+ # # -0.549306
2225
+ # # -inf
2226
+ # # NaN
2227
+ # # ]
2228
+ def arctanh
2229
+ super
2230
+ end
1248
2231
 
1249
- # def sinh
1250
- # end
2232
+ # Compute the element-wise value for the hyperbolic sine.
2233
+ #
2234
+ # @return [Series]
2235
+ #
2236
+ # @example
2237
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2238
+ # s.sinh
2239
+ # # =>
2240
+ # # shape: (3,)
2241
+ # # Series: 'a' [f64]
2242
+ # # [
2243
+ # # 1.175201
2244
+ # # 0.0
2245
+ # # -1.175201
2246
+ # # ]
2247
+ def sinh
2248
+ super
2249
+ end
1251
2250
 
1252
- # def cosh
1253
- # end
2251
+ # Compute the element-wise value for the hyperbolic cosine.
2252
+ #
2253
+ # @return [Series]
2254
+ #
2255
+ # @example
2256
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2257
+ # s.cosh
2258
+ # # =>
2259
+ # # shape: (3,)
2260
+ # # Series: 'a' [f64]
2261
+ # # [
2262
+ # # 1.543081
2263
+ # # 1.0
2264
+ # # 1.543081
2265
+ # # ]
2266
+ def cosh
2267
+ super
2268
+ end
1254
2269
 
1255
- # def tanh
1256
- # end
2270
+ # Compute the element-wise value for the hyperbolic tangent.
2271
+ #
2272
+ # @return [Series]
2273
+ #
2274
+ # @example
2275
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2276
+ # s.tanh
2277
+ # # =>
2278
+ # # shape: (3,)
2279
+ # # Series: 'a' [f64]
2280
+ # # [
2281
+ # # 0.761594
2282
+ # # 0.0
2283
+ # # -0.761594
2284
+ # # ]
2285
+ def tanh
2286
+ super
2287
+ end
1257
2288
 
1258
2289
  # def apply
1259
2290
  # end
1260
2291
 
1261
- # def shift
1262
- # end
2292
+ # Shift the values by a given period.
2293
+ #
2294
+ # @param periods [Integer]
2295
+ # Number of places to shift (may be negative).
2296
+ #
2297
+ # @return [Series]
2298
+ #
2299
+ # @example
2300
+ # s = Polars::Series.new("a", [1, 2, 3])
2301
+ # s.shift(1)
2302
+ # # =>
2303
+ # # shape: (3,)
2304
+ # # Series: 'a' [i64]
2305
+ # # [
2306
+ # # null
2307
+ # # 1
2308
+ # # 2
2309
+ # # ]
2310
+ #
2311
+ # @example
2312
+ # s.shift(-1)
2313
+ # # =>
2314
+ # # shape: (3,)
2315
+ # # Series: 'a' [i64]
2316
+ # # [
2317
+ # # 2
2318
+ # # 3
2319
+ # # null
2320
+ # # ]
2321
+ def shift(periods = 1)
2322
+ super
2323
+ end
1263
2324
 
1264
- # def shift_and_fill
1265
- # end
2325
+ # Shift the values by a given period and fill the resulting null values.
2326
+ #
2327
+ # @param periods [Integer]
2328
+ # Number of places to shift (may be negative).
2329
+ # @param fill_value [Object]
2330
+ # Fill None values with the result of this expression.
2331
+ #
2332
+ # @return [Series]
2333
+ def shift_and_fill(periods, fill_value)
2334
+ super
2335
+ end
1266
2336
 
1267
- # def zip_with
1268
- # end
2337
+ # Take values from self or other based on the given mask.
2338
+ #
2339
+ # Where mask evaluates true, take values from self. Where mask evaluates false,
2340
+ # take values from other.
2341
+ #
2342
+ # @param mask [Series]
2343
+ # Boolean Series.
2344
+ # @param other [Series]
2345
+ # Series of same type.
2346
+ #
2347
+ # @return [Series]
2348
+ #
2349
+ # @example
2350
+ # s1 = Polars::Series.new([1, 2, 3, 4, 5])
2351
+ # s2 = Polars::Series.new([5, 4, 3, 2, 1])
2352
+ # s1.zip_with(s1 < s2, s2)
2353
+ # # =>
2354
+ # # shape: (5,)
2355
+ # # Series: '' [i64]
2356
+ # # [
2357
+ # # 1
2358
+ # # 2
2359
+ # # 3
2360
+ # # 2
2361
+ # # 1
2362
+ # # ]
2363
+ #
2364
+ # @example
2365
+ # mask = Polars::Series.new([true, false, true, false, true])
2366
+ # s1.zip_with(mask, s2)
2367
+ # # =>
2368
+ # # shape: (5,)
2369
+ # # Series: '' [i64]
2370
+ # # [
2371
+ # # 1
2372
+ # # 4
2373
+ # # 3
2374
+ # # 2
2375
+ # # 5
2376
+ # # ]
2377
+ def zip_with(mask, other)
2378
+ Utils.wrap_s(_s.zip_with(mask._s, other._s))
2379
+ end
1269
2380
 
1270
- # def rolling_min
1271
- # end
2381
+ # Apply a rolling min (moving min) over the values in this array.
2382
+ #
2383
+ # A window of length `window_size` will traverse the array. The values that fill
2384
+ # this window will (optionally) be multiplied with the weights given by the
2385
+ # `weight` vector. The resulting values will be aggregated to their sum.
2386
+ #
2387
+ # @param window_size [Integer]
2388
+ # The length of the window.
2389
+ # @param weights [Array]
2390
+ # An optional slice with the same length as the window that will be multiplied
2391
+ # elementwise with the values in the window.
2392
+ # @param min_periods [Integer]
2393
+ # The number of values in the window that should be non-null before computing
2394
+ # a result. If None, it will be set equal to window size.
2395
+ # @param center [Boolean]
2396
+ # Set the labels at the center of the window
2397
+ #
2398
+ # @return [Series]
2399
+ #
2400
+ # @example
2401
+ # s = Polars::Series.new("a", [100, 200, 300, 400, 500])
2402
+ # s.rolling_min(3)
2403
+ # # =>
2404
+ # # shape: (5,)
2405
+ # # Series: 'a' [i64]
2406
+ # # [
2407
+ # # null
2408
+ # # null
2409
+ # # 100
2410
+ # # 200
2411
+ # # 300
2412
+ # # ]
2413
+ def rolling_min(
2414
+ window_size,
2415
+ weights: nil,
2416
+ min_periods: nil,
2417
+ center: false
2418
+ )
2419
+ to_frame
2420
+ .select(
2421
+ Polars.col(name).rolling_min(
2422
+ window_size,
2423
+ weights: weights,
2424
+ min_periods: min_periods,
2425
+ center: center
2426
+ )
2427
+ )
2428
+ .to_series
2429
+ end
1272
2430
 
1273
- # def rolling_max
1274
- # end
2431
+ # Apply a rolling max (moving max) over the values in this array.
2432
+ #
2433
+ # A window of length `window_size` will traverse the array. The values that fill
2434
+ # this window will (optionally) be multiplied with the weights given by the
2435
+ # `weight` vector. The resulting values will be aggregated to their sum.
2436
+ #
2437
+ # @param window_size [Integer]
2438
+ # The length of the window.
2439
+ # @param weights [Array]
2440
+ # An optional slice with the same length as the window that will be multiplied
2441
+ # elementwise with the values in the window.
2442
+ # @param min_periods [Integer]
2443
+ # The number of values in the window that should be non-null before computing
2444
+ # a result. If None, it will be set equal to window size.
2445
+ # @param center [Boolean]
2446
+ # Set the labels at the center of the window
2447
+ #
2448
+ # @return [Series]
2449
+ #
2450
+ # @example
2451
+ # s = Polars::Series.new("a", [100, 200, 300, 400, 500])
2452
+ # s.rolling_max(2)
2453
+ # # =>
2454
+ # # shape: (5,)
2455
+ # # Series: 'a' [i64]
2456
+ # # [
2457
+ # # null
2458
+ # # 200
2459
+ # # 300
2460
+ # # 400
2461
+ # # 500
2462
+ # # ]
2463
+ def rolling_max(
2464
+ window_size,
2465
+ weights: nil,
2466
+ min_periods: nil,
2467
+ center: false
2468
+ )
2469
+ to_frame
2470
+ .select(
2471
+ Polars.col(name).rolling_max(
2472
+ window_size,
2473
+ weights: weights,
2474
+ min_periods: min_periods,
2475
+ center: center
2476
+ )
2477
+ )
2478
+ .to_series
2479
+ end
1275
2480
 
1276
- # def rolling_mean
1277
- # end
2481
+ # Apply a rolling mean (moving mean) over the values in this array.
2482
+ #
2483
+ # A window of length `window_size` will traverse the array. The values that fill
2484
+ # this window will (optionally) be multiplied with the weights given by the
2485
+ # `weight` vector. The resulting values will be aggregated to their sum.
2486
+ #
2487
+ # @param window_size [Integer]
2488
+ # The length of the window.
2489
+ # @param weights [Array]
2490
+ # An optional slice with the same length as the window that will be multiplied
2491
+ # elementwise with the values in the window.
2492
+ # @param min_periods [Integer]
2493
+ # The number of values in the window that should be non-null before computing
2494
+ # a result. If None, it will be set equal to window size.
2495
+ # @param center [Boolean]
2496
+ # Set the labels at the center of the window
2497
+ #
2498
+ # @return [Series]
2499
+ #
2500
+ # @example
2501
+ # s = Polars::Series.new("a", [100, 200, 300, 400, 500])
2502
+ # s.rolling_mean(2)
2503
+ # # =>
2504
+ # # shape: (5,)
2505
+ # # Series: 'a' [f64]
2506
+ # # [
2507
+ # # null
2508
+ # # 150.0
2509
+ # # 250.0
2510
+ # # 350.0
2511
+ # # 450.0
2512
+ # # ]
2513
+ def rolling_mean(
2514
+ window_size,
2515
+ weights: nil,
2516
+ min_periods: nil,
2517
+ center: false
2518
+ )
2519
+ to_frame
2520
+ .select(
2521
+ Polars.col(name).rolling_mean(
2522
+ window_size,
2523
+ weights: weights,
2524
+ min_periods: min_periods,
2525
+ center: center
2526
+ )
2527
+ )
2528
+ .to_series
2529
+ end
1278
2530
 
1279
- # def rolling_sum
1280
- # end
2531
+ # Apply a rolling sum (moving sum) over the values in this array.
2532
+ #
2533
+ # A window of length `window_size` will traverse the array. The values that fill
2534
+ # this window will (optionally) be multiplied with the weights given by the
2535
+ # `weight` vector. The resulting values will be aggregated to their sum.
2536
+ #
2537
+ # @param window_size [Integer]
2538
+ # The length of the window.
2539
+ # @param weights [Array]
2540
+ # An optional slice with the same length as the window that will be multiplied
2541
+ # elementwise with the values in the window.
2542
+ # @param min_periods [Integer]
2543
+ # The number of values in the window that should be non-null before computing
2544
+ # a result. If None, it will be set equal to window size.
2545
+ # @param center [Boolean]
2546
+ # Set the labels at the center of the window
2547
+ #
2548
+ # @return [Series]
2549
+ #
2550
+ # @example
2551
+ # s = Polars::Series.new("a", [1, 2, 3, 4, 5])
2552
+ # s.rolling_sum(2)
2553
+ # # =>
2554
+ # # shape: (5,)
2555
+ # # Series: 'a' [i64]
2556
+ # # [
2557
+ # # null
2558
+ # # 3
2559
+ # # 5
2560
+ # # 7
2561
+ # # 9
2562
+ # # ]
2563
+ def rolling_sum(
2564
+ window_size,
2565
+ weights: nil,
2566
+ min_periods: nil,
2567
+ center: false
2568
+ )
2569
+ to_frame
2570
+ .select(
2571
+ Polars.col(name).rolling_sum(
2572
+ window_size,
2573
+ weights: weights,
2574
+ min_periods: min_periods,
2575
+ center: center
2576
+ )
2577
+ )
2578
+ .to_series
2579
+ end
1281
2580
 
1282
- # def rolling_std
1283
- # end
2581
+ # Compute a rolling std dev.
2582
+ #
2583
+ # A window of length `window_size` will traverse the array. The values that fill
2584
+ # this window will (optionally) be multiplied with the weights given by the
2585
+ # `weight` vector. The resulting values will be aggregated to their sum.
2586
+ #
2587
+ # @param window_size [Integer]
2588
+ # The length of the window.
2589
+ # @param weights [Array]
2590
+ # An optional slice with the same length as the window that will be multiplied
2591
+ # elementwise with the values in the window.
2592
+ # @param min_periods [Integer]
2593
+ # The number of values in the window that should be non-null before computing
2594
+ # a result. If None, it will be set equal to window size.
2595
+ # @param center [Boolean]
2596
+ # Set the labels at the center of the window
2597
+ #
2598
+ # @return [Series]
2599
+ #
2600
+ # @example
2601
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, 4.0, 6.0, 8.0])
2602
+ # s.rolling_std(3)
2603
+ # # =>
2604
+ # # shape: (6,)
2605
+ # # Series: 'a' [f64]
2606
+ # # [
2607
+ # # null
2608
+ # # null
2609
+ # # 1.0
2610
+ # # 1.0
2611
+ # # 1.527525
2612
+ # # 2.0
2613
+ # # ]
2614
+ def rolling_std(
2615
+ window_size,
2616
+ weights: nil,
2617
+ min_periods: nil,
2618
+ center: false
2619
+ )
2620
+ to_frame
2621
+ .select(
2622
+ Polars.col(name).rolling_std(
2623
+ window_size,
2624
+ weights: weights,
2625
+ min_periods: min_periods,
2626
+ center: center
2627
+ )
2628
+ )
2629
+ .to_series
2630
+ end
1284
2631
 
1285
- # def rolling_var
1286
- # end
2632
+ # Compute a rolling variance.
2633
+ #
2634
+ # A window of length `window_size` will traverse the array. The values that fill
2635
+ # this window will (optionally) be multiplied with the weights given by the
2636
+ # `weight` vector. The resulting values will be aggregated to their sum.
2637
+ #
2638
+ # @param window_size [Integer]
2639
+ # The length of the window.
2640
+ # @param weights [Array]
2641
+ # An optional slice with the same length as the window that will be multiplied
2642
+ # elementwise with the values in the window.
2643
+ # @param min_periods [Integer]
2644
+ # The number of values in the window that should be non-null before computing
2645
+ # a result. If None, it will be set equal to window size.
2646
+ # @param center [Boolean]
2647
+ # Set the labels at the center of the window
2648
+ #
2649
+ # @return [Series]
2650
+ #
2651
+ # @example
2652
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, 4.0, 6.0, 8.0])
2653
+ # s.rolling_var(3)
2654
+ # # =>
2655
+ # # shape: (6,)
2656
+ # # Series: 'a' [f64]
2657
+ # # [
2658
+ # # null
2659
+ # # null
2660
+ # # 1.0
2661
+ # # 1.0
2662
+ # # 2.333333
2663
+ # # 4.0
2664
+ # # ]
2665
+ def rolling_var(
2666
+ window_size,
2667
+ weights: nil,
2668
+ min_periods: nil,
2669
+ center: false
2670
+ )
2671
+ to_frame
2672
+ .select(
2673
+ Polars.col(name).rolling_var(
2674
+ window_size,
2675
+ weights: weights,
2676
+ min_periods: min_periods,
2677
+ center: center
2678
+ )
2679
+ )
2680
+ .to_series
2681
+ end
1287
2682
 
1288
2683
  # def rolling_apply
1289
2684
  # end
1290
2685
 
1291
- # def rolling_median
1292
- # end
2686
+ # Compute a rolling median.
2687
+ #
2688
+ # @param window_size [Integer]
2689
+ # The length of the window.
2690
+ # @param weights [Array]
2691
+ # An optional slice with the same length as the window that will be multiplied
2692
+ # elementwise with the values in the window.
2693
+ # @param min_periods [Integer]
2694
+ # The number of values in the window that should be non-null before computing
2695
+ # a result. If None, it will be set equal to window size.
2696
+ # @param center [Boolean]
2697
+ # Set the labels at the center of the window
2698
+ #
2699
+ # @return [Series]
2700
+ #
2701
+ # @example
2702
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, 4.0, 6.0, 8.0])
2703
+ # s.rolling_median(3)
2704
+ # # =>
2705
+ # # shape: (6,)
2706
+ # # Series: 'a' [f64]
2707
+ # # [
2708
+ # # null
2709
+ # # null
2710
+ # # 2.0
2711
+ # # 3.0
2712
+ # # 4.0
2713
+ # # 6.0
2714
+ # # ]
2715
+ def rolling_median(
2716
+ window_size,
2717
+ weights: nil,
2718
+ min_periods: nil,
2719
+ center: false
2720
+ )
2721
+ if min_periods.nil?
2722
+ min_periods = window_size
2723
+ end
1293
2724
 
1294
- # def rolling_quantile
1295
- # end
2725
+ to_frame
2726
+ .select(
2727
+ Polars.col(name).rolling_median(
2728
+ window_size,
2729
+ weights: weights,
2730
+ min_periods: min_periods,
2731
+ center: center
2732
+ )
2733
+ )
2734
+ .to_series
2735
+ end
2736
+
2737
+ # Compute a rolling quantile.
2738
+ #
2739
+ # @param quantile [Float]
2740
+ # Quantile between 0.0 and 1.0.
2741
+ # @param interpolation ["nearest", "higher", "lower", "midpoint", "linear"]
2742
+ # Interpolation method.
2743
+ # @param window_size [Integer]
2744
+ # The length of the window.
2745
+ # @param weights [Array]
2746
+ # An optional slice with the same length as the window that will be multiplied
2747
+ # elementwise with the values in the window.
2748
+ # @param min_periods [Integer]
2749
+ # The number of values in the window that should be non-null before computing
2750
+ # a result. If None, it will be set equal to window size.
2751
+ # @param center [Boolean]
2752
+ # Set the labels at the center of the window
2753
+ #
2754
+ # @return [Series]
2755
+ #
2756
+ # @example
2757
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, 4.0, 6.0, 8.0])
2758
+ # s.rolling_quantile(0.33, window_size: 3)
2759
+ # # =>
2760
+ # # shape: (6,)
2761
+ # # Series: 'a' [f64]
2762
+ # # [
2763
+ # # null
2764
+ # # null
2765
+ # # 1.0
2766
+ # # 2.0
2767
+ # # 3.0
2768
+ # # 4.0
2769
+ # # ]
2770
+ #
2771
+ # @example
2772
+ # s.rolling_quantile(0.33, interpolation: "linear", window_size: 3)
2773
+ # # =>
2774
+ # # shape: (6,)
2775
+ # # Series: 'a' [f64]
2776
+ # # [
2777
+ # # null
2778
+ # # null
2779
+ # # 1.66
2780
+ # # 2.66
2781
+ # # 3.66
2782
+ # # 5.32
2783
+ # # ]
2784
+ def rolling_quantile(
2785
+ quantile,
2786
+ interpolation: "nearest",
2787
+ window_size: 2,
2788
+ weights: nil,
2789
+ min_periods: nil,
2790
+ center: false
2791
+ )
2792
+ if min_periods.nil?
2793
+ min_periods = window_size
2794
+ end
2795
+
2796
+ to_frame
2797
+ .select(
2798
+ Polars.col(name).rolling_quantile(
2799
+ quantile,
2800
+ interpolation: interpolation,
2801
+ window_size: window_size,
2802
+ weights: weights,
2803
+ min_periods: min_periods,
2804
+ center: center
2805
+ )
2806
+ )
2807
+ .to_series
2808
+ end
2809
+
2810
+ # Compute a rolling skew.
2811
+ #
2812
+ # @param window_size [Integer]
2813
+ # Integer size of the rolling window.
2814
+ # @param bias [Boolean]
2815
+ # If false, the calculations are corrected for statistical bias.
2816
+ #
2817
+ # @return [Series]
2818
+ #
2819
+ # @example
2820
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, 4.0, 6.0, 8.0])
2821
+ # s.rolling_skew(3)
2822
+ # # =>
2823
+ # # shape: (6,)
2824
+ # # Series: 'a' [f64]
2825
+ # # [
2826
+ # # null
2827
+ # # null
2828
+ # # 0.0
2829
+ # # 0.0
2830
+ # # 0.381802
2831
+ # # 0.0
2832
+ # # ]
2833
+ def rolling_skew(window_size, bias: true)
2834
+ super
2835
+ end
2836
+
2837
+ # Sample from this Series.
2838
+ #
2839
+ # @param n [Integer]
2840
+ # Number of items to return. Cannot be used with `frac`. Defaults to 1 if
2841
+ # `frac` is None.
2842
+ # @param frac [Float]
2843
+ # Fraction of items to return. Cannot be used with `n`.
2844
+ # @param with_replacement [Boolean]
2845
+ # Allow values to be sampled more than once.
2846
+ # @param shuffle [Boolean]
2847
+ # Shuffle the order of sampled data points.
2848
+ # @param seed [Integer]
2849
+ # Seed for the random number generator. If set to None (default), a random
2850
+ # seed is used.
2851
+ #
2852
+ # @return [Series]
2853
+ #
2854
+ # @example
2855
+ # s = Polars::Series.new("a", [1, 2, 3, 4, 5])
2856
+ # s.sample(n: 2, seed: 0)
2857
+ # # =>
2858
+ # # shape: (2,)
2859
+ # # Series: 'a' [i64]
2860
+ # # [
2861
+ # # 1
2862
+ # # 5
2863
+ # # ]
2864
+ def sample(
2865
+ n: nil,
2866
+ frac: nil,
2867
+ with_replacement: false,
2868
+ shuffle: false,
2869
+ seed: nil
2870
+ )
2871
+ if !n.nil? && !frac.nil?
2872
+ raise ArgumentError, "cannot specify both `n` and `frac`"
2873
+ end
1296
2874
 
1297
- # def rolling_skew
1298
- # end
2875
+ if n.nil? && !frac.nil?
2876
+ return Utils.wrap_s(_s.sample_frac(frac, with_replacement, shuffle, seed))
2877
+ end
1299
2878
 
1300
- # def sample
1301
- # end
2879
+ if n.nil?
2880
+ n = 1
2881
+ end
2882
+ Utils.wrap_s(_s.sample_n(n, with_replacement, shuffle, seed))
2883
+ end
1302
2884
 
1303
2885
  # Get a boolean mask of the local maximum peaks.
1304
2886
  #
@@ -1354,62 +2936,384 @@ module Polars
1354
2936
  _s.n_unique
1355
2937
  end
1356
2938
 
1357
- # def shrink_to_fit
1358
- # end
2939
+ # Shrink Series memory usage.
2940
+ #
2941
+ # Shrinks the underlying array capacity to exactly fit the actual data.
2942
+ # (Note that this function does not change the Series data type).
2943
+ #
2944
+ # @return [Series]
2945
+ def shrink_to_fit(in_place: false)
2946
+ if in_place
2947
+ _s.shrink_to_fit
2948
+ self
2949
+ else
2950
+ series = clone
2951
+ series._s.shrink_to_fit
2952
+ series
2953
+ end
2954
+ end
1359
2955
 
1360
2956
  # def _hash
1361
2957
  # end
1362
2958
 
1363
- # def reinterpret
1364
- # end
2959
+ # Reinterpret the underlying bits as a signed/unsigned integer.
2960
+ #
2961
+ # This operation is only allowed for 64bit integers. For lower bits integers,
2962
+ # you can safely use that cast operation.
2963
+ #
2964
+ # @param signed [Boolean]
2965
+ # If true, reinterpret as `:i64`. Otherwise, reinterpret as `:u64`.
2966
+ #
2967
+ # @return [Series]
2968
+ def reinterpret(signed: true)
2969
+ super
2970
+ end
1365
2971
 
1366
- # def interpolate
1367
- # end
2972
+ # Interpolate intermediate values. The interpolation method is linear.
2973
+ #
2974
+ # @return [Series]
2975
+ #
2976
+ # @example
2977
+ # s = Polars::Series.new("a", [1, 2, nil, nil, 5])
2978
+ # s.interpolate
2979
+ # # =>
2980
+ # # shape: (5,)
2981
+ # # Series: 'a' [i64]
2982
+ # # [
2983
+ # # 1
2984
+ # # 2
2985
+ # # 3
2986
+ # # 4
2987
+ # # 5
2988
+ # # ]
2989
+ def interpolate
2990
+ super
2991
+ end
1368
2992
 
1369
- # def abs
1370
- # end
2993
+ # Compute absolute values.
2994
+ #
2995
+ # @return [Series]
2996
+ def abs
2997
+ super
2998
+ end
1371
2999
 
1372
- # def rank
1373
- # end
3000
+ # Assign ranks to data, dealing with ties appropriately.
3001
+ #
3002
+ # @param method ["average", "min", "max", "dense", "ordinal", "random"]
3003
+ # The method used to assign ranks to tied elements.
3004
+ # The following methods are available (default is 'average'):
3005
+ #
3006
+ # - 'average' : The average of the ranks that would have been assigned to
3007
+ # all the tied values is assigned to each value.
3008
+ # - 'min' : The minimum of the ranks that would have been assigned to all
3009
+ # the tied values is assigned to each value. (This is also referred to
3010
+ # as "competition" ranking.)
3011
+ # - 'max' : The maximum of the ranks that would have been assigned to all
3012
+ # the tied values is assigned to each value.
3013
+ # - 'dense' : Like 'min', but the rank of the next highest element is
3014
+ # assigned the rank immediately after those assigned to the tied
3015
+ # elements.
3016
+ # - 'ordinal' : All values are given a distinct rank, corresponding to
3017
+ # the order that the values occur in the Series.
3018
+ # - 'random' : Like 'ordinal', but the rank for ties is not dependent
3019
+ # on the order that the values occur in the Series.
3020
+ # @param reverse [Boolean]
3021
+ # Reverse the operation.
3022
+ #
3023
+ # @return [Series]
3024
+ #
3025
+ # @example The 'average' method:
3026
+ # s = Polars::Series.new("a", [3, 6, 1, 1, 6])
3027
+ # s.rank
3028
+ # # =>
3029
+ # # shape: (5,)
3030
+ # # Series: 'a' [f32]
3031
+ # # [
3032
+ # # 3.0
3033
+ # # 4.5
3034
+ # # 1.5
3035
+ # # 1.5
3036
+ # # 4.5
3037
+ # # ]
3038
+ #
3039
+ # @example The 'ordinal' method:
3040
+ # s = Polars::Series.new("a", [3, 6, 1, 1, 6])
3041
+ # s.rank(method: "ordinal")
3042
+ # # =>
3043
+ # # shape: (5,)
3044
+ # # Series: 'a' [u32]
3045
+ # # [
3046
+ # # 3
3047
+ # # 4
3048
+ # # 1
3049
+ # # 2
3050
+ # # 5
3051
+ # # ]
3052
+ def rank(method: "average", reverse: false)
3053
+ super
3054
+ end
1374
3055
 
1375
- # def diff
1376
- # end
3056
+ # Calculate the n-th discrete difference.
3057
+ #
3058
+ # @param n [Integer]
3059
+ # Number of slots to shift.
3060
+ # @param null_behavior ["ignore", "drop"]
3061
+ # How to handle null values.
3062
+ #
3063
+ # @return [Series]
3064
+ def diff(n: 1, null_behavior: "ignore")
3065
+ super
3066
+ end
1377
3067
 
1378
- # def pct_change
1379
- # end
3068
+ # Computes percentage change between values.
3069
+ #
3070
+ # Percentage change (as fraction) between current element and most-recent
3071
+ # non-null element at least `n` period(s) before the current element.
3072
+ #
3073
+ # Computes the change from the previous row by default.
3074
+ #
3075
+ # @param n [Integer]
3076
+ # periods to shift for forming percent change.
3077
+ #
3078
+ # @return [Series]
3079
+ #
3080
+ # @example
3081
+ # Polars::Series.new(0..9).pct_change
3082
+ # # =>
3083
+ # # shape: (10,)
3084
+ # # Series: '' [f64]
3085
+ # # [
3086
+ # # null
3087
+ # # inf
3088
+ # # 1.0
3089
+ # # 0.5
3090
+ # # 0.333333
3091
+ # # 0.25
3092
+ # # 0.2
3093
+ # # 0.166667
3094
+ # # 0.142857
3095
+ # # 0.125
3096
+ # # ]
3097
+ #
3098
+ # @example
3099
+ # Polars::Series.new([1, 2, 4, 8, 16, 32, 64, 128, 256, 512]).pct_change(n: 2)
3100
+ # # =>
3101
+ # # shape: (10,)
3102
+ # # Series: '' [f64]
3103
+ # # [
3104
+ # # null
3105
+ # # null
3106
+ # # 3.0
3107
+ # # 3.0
3108
+ # # 3.0
3109
+ # # 3.0
3110
+ # # 3.0
3111
+ # # 3.0
3112
+ # # 3.0
3113
+ # # 3.0
3114
+ # # ]
3115
+ def pct_change(n: 1)
3116
+ super
3117
+ end
1380
3118
 
1381
- # def skew
1382
- # end
3119
+ # Compute the sample skewness of a data set.
3120
+ #
3121
+ # For normally distributed data, the skewness should be about zero. For
3122
+ # unimodal continuous distributions, a skewness value greater than zero means
3123
+ # that there is more weight in the right tail of the distribution. The
3124
+ # function `skewtest` can be used to determine if the skewness value
3125
+ # is close enough to zero, statistically speaking.
3126
+ #
3127
+ # @param bias [Boolean]
3128
+ # If `false`, the calculations are corrected for statistical bias.
3129
+ #
3130
+ # @return [Float, nil]
3131
+ def skew(bias: true)
3132
+ _s.skew(bias)
3133
+ end
1383
3134
 
1384
- # def kurtosis
1385
- # end
3135
+ # Compute the kurtosis (Fisher or Pearson) of a dataset.
3136
+ #
3137
+ # Kurtosis is the fourth central moment divided by the square of the
3138
+ # variance. If Fisher's definition is used, then 3.0 is subtracted from
3139
+ # the result to give 0.0 for a normal distribution.
3140
+ # If bias is false, then the kurtosis is calculated using k statistics to
3141
+ # eliminate bias coming from biased moment estimators
3142
+ #
3143
+ # @param fisher [Boolean]
3144
+ # If `true`, Fisher's definition is used (normal ==> 0.0). If `false`,
3145
+ # Pearson's definition is used (normal ==> 3.0).
3146
+ # @param bias [Boolean]
3147
+ # If `false`, the calculations are corrected for statistical bias.
3148
+ #
3149
+ # @return [Float, nil]
3150
+ def kurtosis(fisher: true, bias: true)
3151
+ _s.kurtosis(fisher, bias)
3152
+ end
1386
3153
 
1387
- # def clip
1388
- # end
3154
+ # Clip (limit) the values in an array to a `min` and `max` boundary.
3155
+ #
3156
+ # Only works for numerical types.
3157
+ #
3158
+ # If you want to clip other dtypes, consider writing a "when, then, otherwise"
3159
+ # expression. See {#when} for more information.
3160
+ #
3161
+ # @param min_val [Numeric]
3162
+ # Minimum value.
3163
+ # @param max_val [Numeric]
3164
+ # Maximum value.
3165
+ #
3166
+ # @return [Series]
3167
+ #
3168
+ # @example
3169
+ # s = Polars::Series.new("foo", [-50, 5, nil, 50])
3170
+ # s.clip(1, 10)
3171
+ # # =>
3172
+ # # shape: (4,)
3173
+ # # Series: 'foo' [i64]
3174
+ # # [
3175
+ # # 1
3176
+ # # 5
3177
+ # # null
3178
+ # # 10
3179
+ # # ]
3180
+ def clip(min_val, max_val)
3181
+ super
3182
+ end
1389
3183
 
1390
- # def clip_min
1391
- # end
3184
+ # Clip (limit) the values in an array to a `min` boundary.
3185
+ #
3186
+ # Only works for numerical types.
3187
+ #
3188
+ # If you want to clip other dtypes, consider writing a "when, then, otherwise"
3189
+ # expression. See {#when} for more information.
3190
+ #
3191
+ # @param min_val [Numeric]
3192
+ # Minimum value.
3193
+ #
3194
+ # @return [Series]
3195
+ def clip_min(min_val)
3196
+ super
3197
+ end
1392
3198
 
1393
- # def clip_max
1394
- # end
3199
+ # Clip (limit) the values in an array to a `max` boundary.
3200
+ #
3201
+ # Only works for numerical types.
3202
+ #
3203
+ # If you want to clip other dtypes, consider writing a "when, then, otherwise"
3204
+ # expression. See {#when} for more information.
3205
+ #
3206
+ # @param max_val [Numeric]
3207
+ # Maximum value.
3208
+ #
3209
+ # @return [Series]
3210
+ def clip_max(max_val)
3211
+ super
3212
+ end
1395
3213
 
1396
- # def reshape
1397
- # end
3214
+ # Reshape this Series to a flat Series or a Series of Lists.
3215
+ #
3216
+ # @param dims [Array]
3217
+ # Tuple of the dimension sizes. If a -1 is used in any of the dimensions, that
3218
+ # dimension is inferred.
3219
+ #
3220
+ # @return [Series]
3221
+ def reshape(dims)
3222
+ super
3223
+ end
1398
3224
 
1399
- # def shuffle
1400
- # end
3225
+ # Shuffle the contents of this Series.
3226
+ #
3227
+ # @param seed [Integer, nil]
3228
+ # Seed for the random number generator.
3229
+ #
3230
+ # @return [Series]
3231
+ #
3232
+ # @example
3233
+ # s = Polars::Series.new("a", [1, 2, 3])
3234
+ # s.shuffle(seed: 1)
3235
+ # # =>
3236
+ # # shape: (3,)
3237
+ # # Series: 'a' [i64]
3238
+ # # [
3239
+ # # 2
3240
+ # # 1
3241
+ # # 3
3242
+ # # ]
3243
+ def shuffle(seed: nil)
3244
+ super
3245
+ end
1401
3246
 
1402
- # def ewm_mean
1403
- # end
3247
+ # Exponentially-weighted moving average.
3248
+ #
3249
+ # @return [Series]
3250
+ def ewm_mean(
3251
+ com: nil,
3252
+ span: nil,
3253
+ half_life: nil,
3254
+ alpha: nil,
3255
+ adjust: true,
3256
+ min_periods: 1
3257
+ )
3258
+ super
3259
+ end
1404
3260
 
1405
- # def ewm_std
1406
- # end
3261
+ # Exponentially-weighted moving standard deviation.
3262
+ #
3263
+ # @return [Series]
3264
+ def ewm_std(
3265
+ com: nil,
3266
+ span: nil,
3267
+ half_life: nil,
3268
+ alpha: nil,
3269
+ adjust: true,
3270
+ bias: false,
3271
+ min_periods: 1
3272
+ )
3273
+ super
3274
+ end
1407
3275
 
1408
- # def ewm_var
1409
- # end
3276
+ # Exponentially-weighted moving variance.
3277
+ #
3278
+ # @return [Series]
3279
+ def ewm_var(
3280
+ com: nil,
3281
+ span: nil,
3282
+ half_life: nil,
3283
+ alpha: nil,
3284
+ adjust: true,
3285
+ bias: false,
3286
+ min_periods: 1
3287
+ )
3288
+ super
3289
+ end
1410
3290
 
1411
- # def extend_constant
1412
- # end
3291
+ # Extend the Series with given number of values.
3292
+ #
3293
+ # @param value [Object]
3294
+ # The value to extend the Series with. This value may be `nil` to fill with
3295
+ # nulls.
3296
+ # @param n [Integer]
3297
+ # The number of values to extend.
3298
+ #
3299
+ # @return [Series]
3300
+ #
3301
+ # @example
3302
+ # s = Polars::Series.new("a", [1, 2, 3])
3303
+ # s.extend_constant(99, 2)
3304
+ # # =>
3305
+ # # shape: (5,)
3306
+ # # Series: 'a' [i64]
3307
+ # # [
3308
+ # # 1
3309
+ # # 2
3310
+ # # 3
3311
+ # # 99
3312
+ # # 99
3313
+ # # ]
3314
+ def extend_constant(value, n)
3315
+ super
3316
+ end
1413
3317
 
1414
3318
  # Flags the Series as sorted.
1415
3319
  #
@@ -1432,26 +3336,57 @@ module Polars
1432
3336
  Utils.wrap_s(_s.set_sorted(reverse))
1433
3337
  end
1434
3338
 
1435
- # def new_from_index
1436
- # end
3339
+ # Create a new Series filled with values from the given index.
3340
+ #
3341
+ # @return [Series]
3342
+ def new_from_index(index, length)
3343
+ Utils.wrap_s(_s.new_from_index(index, length))
3344
+ end
1437
3345
 
1438
- # def shrink_dtype
1439
- # end
3346
+ # Shrink numeric columns to the minimal required datatype.
3347
+ #
3348
+ # Shrink to the dtype needed to fit the extrema of this Series.
3349
+ # This can be used to reduce memory pressure.
3350
+ #
3351
+ # @return [Series]
3352
+ def shrink_dtype
3353
+ super
3354
+ end
1440
3355
 
1441
- # def arr
1442
- # end
3356
+ # Create an object namespace of all list related methods.
3357
+ #
3358
+ # @return [ListNameSpace]
3359
+ def arr
3360
+ ListNameSpace.new(self)
3361
+ end
1443
3362
 
1444
- # def cat
1445
- # end
3363
+ # Create an object namespace of all categorical related methods.
3364
+ #
3365
+ # @return [CatNameSpace]
3366
+ def cat
3367
+ CatNameSpace.new(self)
3368
+ end
1446
3369
 
1447
- # def dt
1448
- # end
3370
+ # Create an object namespace of all datetime related methods.
3371
+ #
3372
+ # @return [DateTimeNameSpace]
3373
+ def dt
3374
+ DateTimeNameSpace.new(self)
3375
+ end
1449
3376
 
1450
- # def str
1451
- # end
3377
+ # Create an object namespace of all string related methods.
3378
+ #
3379
+ # @return [StringNameSpace]
3380
+ def str
3381
+ StringNameSpace.new(self)
3382
+ end
1452
3383
 
1453
- # def struct
1454
- # end
3384
+ # Create an object namespace of all struct related methods.
3385
+ #
3386
+ # @return [StructNameSpace]
3387
+ def struct
3388
+ StructNameSpace.new(self)
3389
+ end
1455
3390
 
1456
3391
  private
1457
3392
 
@@ -1460,8 +3395,47 @@ module Polars
1460
3395
  self._s = _s._clone
1461
3396
  end
1462
3397
 
3398
+ def coerce(other)
3399
+ if other.is_a?(Numeric)
3400
+ # TODO improve
3401
+ series = to_frame.select(Polars.lit(other)).to_series
3402
+ [series, self]
3403
+ else
3404
+ raise TypeError, "#{self.class} can't be coerced into #{other.class}"
3405
+ end
3406
+ end
3407
+
3408
+ def _comp(other, op)
3409
+ if other.is_a?(Series)
3410
+ return Utils.wrap_s(_s.send(op, other._s))
3411
+ end
3412
+
3413
+ if dtype == :str
3414
+ raise Todo
3415
+ end
3416
+ Utils.wrap_s(_s.send("#{op}_#{dtype}", other))
3417
+ end
3418
+
3419
+ def _arithmetic(other, op)
3420
+ if other.is_a?(Expr)
3421
+ other = to_frame.select(other).to_series
3422
+ end
3423
+ if other.is_a?(Series)
3424
+ return Utils.wrap_s(_s.send(op, other._s))
3425
+ end
3426
+
3427
+ raise Todo
3428
+ end
3429
+
3430
+ def series_to_rbseries(name, values)
3431
+ # should not be in-place?
3432
+ values.rename(name, in_place: true)
3433
+ values._s
3434
+ end
3435
+
1463
3436
  def sequence_to_rbseries(name, values, dtype: nil, strict: true, dtype_if_empty: nil)
1464
3437
  ruby_dtype = nil
3438
+ nested_dtype = nil
1465
3439
 
1466
3440
  if (values.nil? || values.empty?) && dtype.nil?
1467
3441
  if dtype_if_empty
@@ -1470,7 +3444,7 @@ module Polars
1470
3444
  dtype = dtype_if_empty
1471
3445
  else
1472
3446
  # default to Float32 type
1473
- dtype = "f32"
3447
+ dtype = :f32
1474
3448
  end
1475
3449
  end
1476
3450
 
@@ -1479,8 +3453,7 @@ module Polars
1479
3453
  rb_temporal_types << DateTime if defined?(DateTime)
1480
3454
  rb_temporal_types << Time if defined?(Time)
1481
3455
 
1482
- # _get_first_non_none
1483
- value = values.find { |v| !v.nil? }
3456
+ value = _get_first_non_none(values)
1484
3457
 
1485
3458
  if !dtype.nil? && Utils.is_polars_dtype(dtype) && ruby_dtype.nil?
1486
3459
  constructor = polars_type_to_constructor(dtype)
@@ -1504,7 +3477,45 @@ module Polars
1504
3477
  # dtype = rb_type_to_dtype(dtype)
1505
3478
  # end
1506
3479
 
1507
- raise Todo
3480
+ if ruby_dtype == Date
3481
+ RbSeries.new_opt_date(name, values, strict)
3482
+ elsif ruby_dtype == Time
3483
+ RbSeries.new_opt_datetime(name, values, strict)
3484
+ elsif ruby_dtype == DateTime
3485
+ RbSeries.new_opt_datetime(name, values.map(&:to_time), strict)
3486
+ else
3487
+ raise Todo
3488
+ end
3489
+ elsif ruby_dtype == Array
3490
+ if nested_dtype.nil?
3491
+ nested_value = _get_first_non_none(value)
3492
+ nested_dtype = nested_value.nil? ? Float : nested_value.class
3493
+ end
3494
+
3495
+ if nested_dtype == Array
3496
+ raise Todo
3497
+ end
3498
+
3499
+ if value.is_a?(Array)
3500
+ count = 0
3501
+ equal_to_inner = true
3502
+ values.each do |lst|
3503
+ lst.each do |vl|
3504
+ equal_to_inner = vl.class == nested_dtype
3505
+ if !equal_to_inner || count > 50
3506
+ break
3507
+ end
3508
+ count += 1
3509
+ end
3510
+ end
3511
+ if equal_to_inner
3512
+ dtype = Utils.rb_type_to_dtype(nested_dtype)
3513
+ # TODO rescue and fallback to new_object
3514
+ return RbSeries.new_list(name, values, dtype)
3515
+ end
3516
+ end
3517
+
3518
+ RbSeries.new_object(name, values, strict)
1508
3519
  else
1509
3520
  constructor = rb_type_to_constructor(value.class)
1510
3521
  constructor.call(name, values, strict)
@@ -1544,8 +3555,11 @@ module Polars
1544
3555
  def rb_type_to_constructor(dtype)
1545
3556
  RB_TYPE_TO_CONSTRUCTOR.fetch(dtype)
1546
3557
  rescue KeyError
1547
- # RbSeries.method(:new_object)
1548
- raise ArgumentError, "Cannot determine type"
3558
+ RbSeries.method(:new_object)
3559
+ end
3560
+
3561
+ def _get_first_non_none(values)
3562
+ values.find { |v| !v.nil? }
1549
3563
  end
1550
3564
  end
1551
3565
  end