polars-df 0.1.2 → 0.1.3

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.
data/lib/polars/series.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  module Polars
2
2
  # A Series represents a single column in a polars DataFrame.
3
3
  class Series
4
+ include ExprDispatch
5
+
4
6
  # @private
5
7
  attr_accessor :_s
6
8
 
@@ -48,6 +50,8 @@ module Polars
48
50
 
49
51
  if values.nil?
50
52
  self._s = sequence_to_rbseries(name, [], dtype: dtype, dtype_if_empty: dtype_if_empty)
53
+ elsif values.is_a?(Series)
54
+ self._s = series_to_rbseries(name, values)
51
55
  elsif values.is_a?(Range)
52
56
  self._s =
53
57
  Polars.arange(
@@ -130,6 +134,9 @@ module Polars
130
134
  #
131
135
  # @return [Series]
132
136
  def &(other)
137
+ if !other.is_a?(Series)
138
+ other = Series.new([other])
139
+ end
133
140
  Utils.wrap_s(_s.bitand(other._s))
134
141
  end
135
142
 
@@ -137,6 +144,9 @@ module Polars
137
144
  #
138
145
  # @return [Series]
139
146
  def |(other)
147
+ if !other.is_a?(Series)
148
+ other = Series.new([other])
149
+ end
140
150
  Utils.wrap_s(_s.bitor(other._s))
141
151
  end
142
152
 
@@ -144,53 +154,90 @@ module Polars
144
154
  #
145
155
  # @return [Series]
146
156
  def ^(other)
157
+ if !other.is_a?(Series)
158
+ other = Series.new([other])
159
+ end
147
160
  Utils.wrap_s(_s.bitxor(other._s))
148
161
  end
149
162
 
150
- # def ==(other)
151
- # end
163
+ # Equal.
164
+ #
165
+ # @return [Series]
166
+ def ==(other)
167
+ _comp(other, :eq)
168
+ end
152
169
 
153
- # def !=(other)
154
- # end
170
+ # Not equal.
171
+ #
172
+ # @return [Series]
173
+ def !=(other)
174
+ _comp(other, :neq)
175
+ end
155
176
 
156
- # def >(other)
157
- # end
177
+ # Greater than.
178
+ #
179
+ # @return [Series]
180
+ def >(other)
181
+ _comp(other, :gt)
182
+ end
158
183
 
159
- # def <(other)
160
- # end
184
+ # Less than.
185
+ #
186
+ # @return [Series]
187
+ def <(other)
188
+ _comp(other, :lt)
189
+ end
161
190
 
162
- # def >=(other)
163
- # end
191
+ # Greater than or equal.
192
+ #
193
+ # @return [Series]
194
+ def >=(other)
195
+ _comp(other, :gt_eq)
196
+ end
164
197
 
165
- # def <=(other)
166
- # end
198
+ # Less than or equal.
199
+ #
200
+ # @return [Series]
201
+ def <=(other)
202
+ _comp(other, :lt_eq)
203
+ end
167
204
 
168
205
  # Performs addition.
169
206
  #
170
207
  # @return [Series]
171
208
  def +(other)
172
- Utils. wrap_s(_s.add(other._s))
209
+ _arithmetic(other, :add)
173
210
  end
174
211
 
175
212
  # Performs subtraction.
176
213
  #
177
214
  # @return [Series]
178
215
  def -(other)
179
- Utils.wrap_s(_s.sub(other._s))
216
+ _arithmetic(other, :sub)
180
217
  end
181
218
 
182
219
  # Performs multiplication.
183
220
  #
184
221
  # @return [Series]
185
222
  def *(other)
186
- Utils.wrap_s(_s.mul(other._s))
223
+ _arithmetic(other, :mul)
187
224
  end
188
225
 
189
226
  # Performs division.
190
227
  #
191
228
  # @return [Series]
192
229
  def /(other)
193
- Utils.wrap_s(_s.div(other._s))
230
+ _arithmetic(other, :div)
231
+ end
232
+
233
+ # Returns the modulo.
234
+ #
235
+ # @return [Series]
236
+ def %(other)
237
+ if is_datelike
238
+ raise ArgumentError, "first cast to integer before applying modulo on datelike dtypes"
239
+ end
240
+ _arithmetic(other, :rem)
194
241
  end
195
242
 
196
243
  # Raises to the power of exponent.
@@ -203,18 +250,63 @@ module Polars
203
250
  to_frame.select(Polars.col(name).pow(power)).to_series
204
251
  end
205
252
 
206
- # def -@(other)
207
- # end
253
+ # Performs negation.
254
+ #
255
+ # @return [Series]
256
+ def -@
257
+ 0 - self
258
+ end
208
259
 
209
260
  # Returns elements of the Series.
210
261
  #
211
262
  # @return [Object]
212
263
  def [](item)
213
- _s.get_idx(item)
264
+ if item.is_a?(Integer)
265
+ return _s.get_idx(item)
266
+ end
267
+
268
+ if item.is_a?(Range)
269
+ return Slice.new(self).apply(item)
270
+ end
271
+
272
+ raise ArgumentError, "Cannot get item of type: #{item.class.name}"
214
273
  end
215
274
 
216
- # def []=(key, value)
217
- # end
275
+ # Sets an element of the Series.
276
+ #
277
+ # @return [Object]
278
+ def []=(key, value)
279
+ if value.is_a?(Array)
280
+ if is_numeric || is_datelike
281
+ set_at_idx(key, value)
282
+ return
283
+ end
284
+ raise ArgumentError, "cannot set Series of dtype: #{dtype} with list/tuple as value; use a scalar value"
285
+ end
286
+
287
+ if key.is_a?(Series)
288
+ if key.dtype == :bool
289
+ self._s = set(key, value)._s
290
+ elsif key.dtype == :u64
291
+ self._s = set_at_idx(key.cast(:u32), value)._s
292
+ elsif key.dtype == :u32
293
+ self._s = set_at_idx(key, value)._s
294
+ else
295
+ raise Todo
296
+ end
297
+ end
298
+
299
+ if key.is_a?(Array)
300
+ s = Utils.wrap_s(sequence_to_rbseries("", key, dtype: :u32))
301
+ self[s] = value
302
+ elsif key.is_a?(Integer)
303
+ # TODO fix
304
+ # self[[key]] = value
305
+ set_at_idx(key, value)
306
+ else
307
+ raise ArgumentError, "cannot use #{key} for indexing"
308
+ end
309
+ end
218
310
 
219
311
  # Return an estimation of the total (heap) allocated size of the Series.
220
312
  #
@@ -268,20 +360,43 @@ module Polars
268
360
  to_frame.select(Polars.col(name).all).to_series[0]
269
361
  end
270
362
 
271
- # def log
272
- # end
363
+ # Compute the logarithm to a given base.
364
+ #
365
+ # @param base [Float]
366
+ # Given base, defaults to `Math::E`.
367
+ #
368
+ # @return [Series]
369
+ def log(base = Math::E)
370
+ super
371
+ end
273
372
 
274
- # def log10
275
- # end
373
+ # Compute the base 10 logarithm of the input array, element-wise.
374
+ #
375
+ # @return [Series]
376
+ def log10
377
+ super
378
+ end
276
379
 
277
- # def exp
278
- # end
380
+ # Compute the exponential, element-wise.
381
+ #
382
+ # @return [Series]
383
+ def exp
384
+ super
385
+ end
279
386
 
280
- # def drop_nulls
281
- # end
387
+ # Create a new Series that copies data from this Series without null values.
388
+ #
389
+ # @return [Series]
390
+ def drop_nulls
391
+ super
392
+ end
282
393
 
283
- # def drop_nans
284
- # end
394
+ # Drop NaN values.
395
+ #
396
+ # @return [Series]
397
+ def drop_nans
398
+ super
399
+ end
285
400
 
286
401
  # Cast this Series to a DataFrame.
287
402
  #
@@ -290,8 +405,94 @@ module Polars
290
405
  Utils.wrap_df(RbDataFrame.new([_s]))
291
406
  end
292
407
 
293
- # def describe
294
- # end
408
+ # Quick summary statistics of a series.
409
+ #
410
+ # Series with mixed datatypes will return summary statistics for the datatype of
411
+ # the first value.
412
+ #
413
+ # @return [DataFrame]
414
+ #
415
+ # @example
416
+ # series_num = Polars::Series.new([1, 2, 3, 4, 5])
417
+ # series_num.describe
418
+ # # =>
419
+ # # shape: (6, 2)
420
+ # # ┌────────────┬──────────┐
421
+ # # │ statistic ┆ value │
422
+ # # │ --- ┆ --- │
423
+ # # │ str ┆ f64 │
424
+ # # ╞════════════╪══════════╡
425
+ # # │ min ┆ 1.0 │
426
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
427
+ # # │ max ┆ 5.0 │
428
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
429
+ # # │ null_count ┆ 0.0 │
430
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
431
+ # # │ mean ┆ 3.0 │
432
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
433
+ # # │ std ┆ 1.581139 │
434
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
435
+ # # │ count ┆ 5.0 │
436
+ # # └────────────┴──────────┘
437
+ #
438
+ # @example
439
+ # series_str = Polars::Series.new(["a", "a", nil, "b", "c"])
440
+ # series_str.describe
441
+ # # =>
442
+ # # shape: (3, 2)
443
+ # # ┌────────────┬───────┐
444
+ # # │ statistic ┆ value │
445
+ # # │ --- ┆ --- │
446
+ # # │ str ┆ i64 │
447
+ # # ╞════════════╪═══════╡
448
+ # # │ unique ┆ 4 │
449
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
450
+ # # │ null_count ┆ 1 │
451
+ # # ├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
452
+ # # │ count ┆ 5 │
453
+ # # └────────────┴───────┘
454
+ def describe
455
+ if len == 0
456
+ raise ArgumentError, "Series must contain at least one value"
457
+ elsif is_numeric
458
+ s = cast(:f64)
459
+ stats = {
460
+ "min" => s.min,
461
+ "max" => s.max,
462
+ "null_count" => s.null_count,
463
+ "mean" => s.mean,
464
+ "std" => s.std,
465
+ "count" => s.len
466
+ }
467
+ elsif is_boolean
468
+ stats = {
469
+ "sum" => sum,
470
+ "null_count" => null_count,
471
+ "count" => len
472
+ }
473
+ elsif is_utf8
474
+ stats = {
475
+ "unique" => unique.length,
476
+ "null_count" => null_count,
477
+ "count" => len
478
+ }
479
+ elsif is_datelike
480
+ # we coerce all to string, because a polars column
481
+ # only has a single dtype and dates: datetime and count: int don't match
482
+ stats = {
483
+ "min" => dt.min.to_s,
484
+ "max" => dt.max.to_s,
485
+ "null_count" => null_count.to_s,
486
+ "count" => len.to_s
487
+ }
488
+ else
489
+ raise TypeError, "This type is not supported"
490
+ end
491
+
492
+ Polars::DataFrame.new(
493
+ {"statistic" => stats.keys, "value" => stats.values}
494
+ )
495
+ end
295
496
 
296
497
  # Reduce this Series to the sum value.
297
498
  #
@@ -352,11 +553,19 @@ module Polars
352
553
  _s.max
353
554
  end
354
555
 
355
- # def nan_max
356
- # end
556
+ # Get maximum value, but propagate/poison encountered NaN values.
557
+ #
558
+ # @return [Object]
559
+ def nan_max
560
+ to_frame.select(Polars.col(name).nan_max)[0, 0]
561
+ end
357
562
 
358
- # def nan_min
359
- # end
563
+ # Get minimum value, but propagate/poison encountered NaN values.
564
+ #
565
+ # @return [Object]
566
+ def nan_min
567
+ to_frame.select(Polars.col(name).nan_min)[0, 0]
568
+ end
360
569
 
361
570
  # Get the standard deviation of this Series.
362
571
  #
@@ -478,11 +687,48 @@ module Polars
478
687
  Utils.wrap_df(_s.value_counts(sort))
479
688
  end
480
689
 
481
- # def unique_counts
482
- # end
690
+ # Return a count of the unique values in the order of appearance.
691
+ #
692
+ # @return [Series]
693
+ #
694
+ # @example
695
+ # s = Polars::Series.new("id", ["a", "b", "b", "c", "c", "c"])
696
+ # s.unique_counts
697
+ # # =>
698
+ # # shape: (3,)
699
+ # # Series: 'id' [u32]
700
+ # # [
701
+ # # 1
702
+ # # 2
703
+ # # 3
704
+ # # ]
705
+ def unique_counts
706
+ super
707
+ end
483
708
 
484
- # def entropy
485
- # end
709
+ # Computes the entropy.
710
+ #
711
+ # Uses the formula `-sum(pk * log(pk)` where `pk` are discrete probabilities.
712
+ #
713
+ # @param base [Float]
714
+ # Given base, defaults to `e`
715
+ # @param normalize [Boolean]
716
+ # Normalize pk if it doesn't sum to 1.
717
+ #
718
+ # @return [Float, nil]
719
+ #
720
+ # @example
721
+ # a = Polars::Series.new([0.99, 0.005, 0.005])
722
+ # a.entropy(normalize: true)
723
+ # # => 0.06293300616044681
724
+ #
725
+ # @example
726
+ # b = Polars::Series.new([0.65, 0.10, 0.25])
727
+ # b.entropy(normalize: true)
728
+ # # => 0.8568409950394724
729
+ def entropy(base: Math::E, normalize: false)
730
+ Polars.select(Polars.lit(self).entropy(base: base, normalize: normalize)).to_series[0]
731
+ end
486
732
 
487
733
  # def cumulative_eval
488
734
  # end
@@ -585,7 +831,7 @@ module Polars
585
831
  # # 6
586
832
  # # ]
587
833
  def cumsum(reverse: false)
588
- Utils.wrap_s(_s.cumsum(reverse))
834
+ super
589
835
  end
590
836
 
591
837
  # Get an array with the cumulative min computed at every element.
@@ -607,7 +853,7 @@ module Polars
607
853
  # # 1
608
854
  # # ]
609
855
  def cummin(reverse: false)
610
- Utils.wrap_s(_s.cummin(reverse))
856
+ super
611
857
  end
612
858
 
613
859
  # Get an array with the cumulative max computed at every element.
@@ -629,7 +875,7 @@ module Polars
629
875
  # # 5
630
876
  # # ]
631
877
  def cummax(reverse: false)
632
- Utils.wrap_s(_s.cummax(reverse))
878
+ super
633
879
  end
634
880
 
635
881
  # Get an array with the cumulative product computed at every element.
@@ -655,7 +901,7 @@ module Polars
655
901
  # # 6
656
902
  # # ]
657
903
  def cumprod(reverse: false)
658
- Utils.wrap_s(_s.cumprod(reverse))
904
+ super
659
905
  end
660
906
 
661
907
  # Get the first `n` rows.
@@ -702,8 +948,7 @@ module Polars
702
948
  # # 3
703
949
  # # ]
704
950
  def slice(offset, length = nil)
705
- length = len if length.nil?
706
- Utils.wrap_s(_s.slice(offset, length))
951
+ super
707
952
  end
708
953
 
709
954
  # Append a Series to this one.
@@ -835,8 +1080,23 @@ module Polars
835
1080
  to_frame.select(Utils.col(name).tail(n)).to_series
836
1081
  end
837
1082
 
838
- # def take_every
839
- # end
1083
+ # Take every nth value in the Series and return as new Series.
1084
+ #
1085
+ # @return [Series]
1086
+ #
1087
+ # @example
1088
+ # s = Polars::Series.new("a", [1, 2, 3, 4])
1089
+ # s.take_every(2)
1090
+ # # =>
1091
+ # # shape: (2,)
1092
+ # # Series: 'a' [i64]
1093
+ # # [
1094
+ # # 1
1095
+ # # 3
1096
+ # # ]
1097
+ def take_every(n)
1098
+ super
1099
+ end
840
1100
 
841
1101
  # Sort this Series.
842
1102
  #
@@ -878,17 +1138,78 @@ module Polars
878
1138
  end
879
1139
  end
880
1140
 
881
- # def top_k
882
- # end
1141
+ # Return the `k` largest elements.
1142
+ #
1143
+ # If `reverse: true`, the smallest elements will be given.
1144
+ #
1145
+ # @param k [Integer]
1146
+ # Number of elements to return.
1147
+ # @param reverse [Boolean]
1148
+ # Return the smallest elements.
1149
+ #
1150
+ # @return [Boolean]
1151
+ def top_k(k: 5, reverse: false)
1152
+ super
1153
+ end
883
1154
 
884
- # def arg_sort
885
- # end
1155
+ # Get the index values that would sort this Series.
1156
+ #
1157
+ # @param reverse [Boolean]
1158
+ # Sort in reverse (descending) order.
1159
+ # @param nulls_last [Boolean]
1160
+ # Place null values last instead of first.
1161
+ #
1162
+ # @return [Series]
1163
+ #
1164
+ # @example
1165
+ # s = Polars::Series.new("a", [5, 3, 4, 1, 2])
1166
+ # s.arg_sort
1167
+ # # =>
1168
+ # # shape: (5,)
1169
+ # # Series: 'a' [u32]
1170
+ # # [
1171
+ # # 3
1172
+ # # 4
1173
+ # # 1
1174
+ # # 2
1175
+ # # 0
1176
+ # # ]
1177
+ def arg_sort(reverse: false, nulls_last: false)
1178
+ super
1179
+ end
886
1180
 
887
- # def argsort
888
- # end
1181
+ # Get the index values that would sort this Series.
1182
+ #
1183
+ # Alias for {#arg_sort}.
1184
+ #
1185
+ # @param reverse [Boolean]
1186
+ # Sort in reverse (descending) order.
1187
+ # @param nulls_last [Boolean]
1188
+ # Place null values last instead of first.
1189
+ #
1190
+ # @return [Series]
1191
+ def argsort(reverse: false, nulls_last: false)
1192
+ super
1193
+ end
889
1194
 
890
- # def arg_unique
891
- # end
1195
+ # Get unique index as Series.
1196
+ #
1197
+ # @return [Series]
1198
+ #
1199
+ # @example
1200
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1201
+ # s.arg_unique
1202
+ # # =>
1203
+ # # shape: (3,)
1204
+ # # Series: 'a' [u32]
1205
+ # # [
1206
+ # # 0
1207
+ # # 1
1208
+ # # 3
1209
+ # # ]
1210
+ def arg_unique
1211
+ super
1212
+ end
892
1213
 
893
1214
  # Get the index of the minimal value.
894
1215
  #
@@ -914,14 +1235,58 @@ module Polars
914
1235
  _s.arg_max
915
1236
  end
916
1237
 
917
- # def search_sorted
918
- # end
1238
+ # Find indices where elements should be inserted to maintain order.
1239
+ #
1240
+ # @param element [Object]
1241
+ # Expression or scalar value.
1242
+ #
1243
+ # @return [Integer]
1244
+ def search_sorted(element)
1245
+ Polars.select(Polars.lit(self).search_sorted(element))[0, 0]
1246
+ end
919
1247
 
920
- # def unique
921
- # end
1248
+ # Get unique elements in series.
1249
+ #
1250
+ # @param maintain_order [Boolean]
1251
+ # Maintain order of data. This requires more work.
1252
+ #
1253
+ # @return [Series]
1254
+ #
1255
+ # @example
1256
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1257
+ # s.unique.sort
1258
+ # # =>
1259
+ # # shape: (3,)
1260
+ # # Series: 'a' [i64]
1261
+ # # [
1262
+ # # 1
1263
+ # # 2
1264
+ # # 3
1265
+ # # ]
1266
+ def unique(maintain_order: false)
1267
+ super
1268
+ end
922
1269
 
923
- # def take
924
- # end
1270
+ # Take values by index.
1271
+ #
1272
+ # @param indices [Array]
1273
+ # Index location used for selection.
1274
+ #
1275
+ # @return [Series]
1276
+ #
1277
+ # @example
1278
+ # s = Polars::Series.new("a", [1, 2, 3, 4])
1279
+ # s.take([1, 3])
1280
+ # # =>
1281
+ # # shape: (2,)
1282
+ # # Series: 'a' [i64]
1283
+ # # [
1284
+ # # 2
1285
+ # # 4
1286
+ # # ]
1287
+ def take(indices)
1288
+ to_frame.select(Polars.col(name).take(indices)).to_series
1289
+ end
925
1290
 
926
1291
  # Count the null values in this Series.
927
1292
  #
@@ -930,7 +1295,7 @@ module Polars
930
1295
  _s.null_count
931
1296
  end
932
1297
 
933
- # Return True if the Series has a validity bitmask.
1298
+ # Return `true` if the Series has a validity bitmask.
934
1299
  #
935
1300
  # If there is none, it means that there are no null values.
936
1301
  # Use this to swiftly assert a Series does not have null values.
@@ -953,41 +1318,214 @@ module Polars
953
1318
  end
954
1319
  alias_method :empty?, :is_empty
955
1320
 
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
967
-
968
- # def is_nan
969
- # end
1321
+ # Returns a boolean Series indicating which values are null.
1322
+ #
1323
+ # @return [Series]
1324
+ #
1325
+ # @example
1326
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, nil])
1327
+ # s.is_null
1328
+ # # =>
1329
+ # # shape: (4,)
1330
+ # # Series: 'a' [bool]
1331
+ # # [
1332
+ # # false
1333
+ # # false
1334
+ # # false
1335
+ # # true
1336
+ # # ]
1337
+ def is_null
1338
+ super
1339
+ end
970
1340
 
971
- # def is_not_nan
972
- # end
1341
+ # Returns a boolean Series indicating which values are not null.
1342
+ #
1343
+ # @return [Series]
1344
+ #
1345
+ # @example
1346
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, nil])
1347
+ # s.is_not_null
1348
+ # # =>
1349
+ # # shape: (4,)
1350
+ # # Series: 'a' [bool]
1351
+ # # [
1352
+ # # true
1353
+ # # true
1354
+ # # true
1355
+ # # false
1356
+ # # ]
1357
+ def is_not_null
1358
+ super
1359
+ end
1360
+
1361
+ # Returns a boolean Series indicating which values are finite.
1362
+ #
1363
+ # @return [Series]
1364
+ #
1365
+ # @example
1366
+ # s = Polars::Series.new("a", [1.0, 2.0, Float::INFINITY])
1367
+ # s.is_finite
1368
+ # # =>
1369
+ # # shape: (3,)
1370
+ # # Series: 'a' [bool]
1371
+ # # [
1372
+ # # true
1373
+ # # true
1374
+ # # false
1375
+ # # ]
1376
+ def is_finite
1377
+ super
1378
+ end
1379
+
1380
+ # Returns a boolean Series indicating which values are infinite.
1381
+ #
1382
+ # @return [Series]
1383
+ #
1384
+ # @example
1385
+ # s = Polars::Series.new("a", [1.0, 2.0, Float::INFINITY])
1386
+ # s.is_infinite
1387
+ # # =>
1388
+ # # shape: (3,)
1389
+ # # Series: 'a' [bool]
1390
+ # # [
1391
+ # # false
1392
+ # # false
1393
+ # # true
1394
+ # # ]
1395
+ def is_infinite
1396
+ super
1397
+ end
1398
+
1399
+ # Returns a boolean Series indicating which values are NaN.
1400
+ #
1401
+ # @return [Series]
1402
+ #
1403
+ # @example
1404
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, Float::NAN])
1405
+ # s.is_nan
1406
+ # # =>
1407
+ # # shape: (4,)
1408
+ # # Series: 'a' [bool]
1409
+ # # [
1410
+ # # false
1411
+ # # false
1412
+ # # false
1413
+ # # true
1414
+ # # ]
1415
+ def is_nan
1416
+ super
1417
+ end
1418
+
1419
+ # Returns a boolean Series indicating which values are not NaN.
1420
+ #
1421
+ # @return [Series]
1422
+ #
1423
+ # @example
1424
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, Float::NAN])
1425
+ # s.is_not_nan
1426
+ # # =>
1427
+ # # shape: (4,)
1428
+ # # Series: 'a' [bool]
1429
+ # # [
1430
+ # # true
1431
+ # # true
1432
+ # # true
1433
+ # # false
1434
+ # # ]
1435
+ def is_not_nan
1436
+ super
1437
+ end
973
1438
 
974
1439
  # def is_in
975
1440
  # end
976
1441
 
977
- # def arg_true
978
- # end
1442
+ # Get index values where Boolean Series evaluate `true`.
1443
+ #
1444
+ # @return [Series]
1445
+ #
1446
+ # @example
1447
+ # s = Polars::Series.new("a", [1, 2, 3])
1448
+ # (s == 2).arg_true
1449
+ # # =>
1450
+ # # shape: (1,)
1451
+ # # Series: 'a' [u32]
1452
+ # # [
1453
+ # # 1
1454
+ # # ]
1455
+ def arg_true
1456
+ Polars.arg_where(self, eager: true)
1457
+ end
979
1458
 
980
- # def is_unique
981
- # end
1459
+ # Get mask of all unique values.
1460
+ #
1461
+ # @return [Series]
1462
+ #
1463
+ # @example
1464
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1465
+ # s.is_unique
1466
+ # # =>
1467
+ # # shape: (4,)
1468
+ # # Series: 'a' [bool]
1469
+ # # [
1470
+ # # true
1471
+ # # false
1472
+ # # false
1473
+ # # true
1474
+ # # ]
1475
+ def is_unique
1476
+ super
1477
+ end
982
1478
 
983
- # def is_first
984
- # end
1479
+ # Get a mask of the first unique value.
1480
+ #
1481
+ # @return [Series]
1482
+ def is_first
1483
+ super
1484
+ end
985
1485
 
986
- # def is_duplicated
987
- # end
1486
+ # Get mask of all duplicated values.
1487
+ #
1488
+ # @return [Series]
1489
+ #
1490
+ # @example
1491
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1492
+ # s.is_duplicated
1493
+ # # =>
1494
+ # # shape: (4,)
1495
+ # # Series: 'a' [bool]
1496
+ # # [
1497
+ # # false
1498
+ # # true
1499
+ # # true
1500
+ # # false
1501
+ # # ]
1502
+ def is_duplicated
1503
+ super
1504
+ end
988
1505
 
989
- # def explode
990
- # end
1506
+ # Explode a list or utf8 Series.
1507
+ #
1508
+ # This means that every item is expanded to a new row.
1509
+ #
1510
+ # @return [Series]
1511
+ #
1512
+ # @example
1513
+ # s = Polars::Series.new("a", [[1, 2], [3, 4], [9, 10]])
1514
+ # s.explode
1515
+ # # =>
1516
+ # # shape: (6,)
1517
+ # # Series: 'a' [i64]
1518
+ # # [
1519
+ # # 1
1520
+ # # 2
1521
+ # # 3
1522
+ # # 4
1523
+ # # 9
1524
+ # # 10
1525
+ # # ]
1526
+ def explode
1527
+ super
1528
+ end
991
1529
 
992
1530
  # Check if series is equal with another Series.
993
1531
  #
@@ -1025,8 +1563,29 @@ module Polars
1025
1563
  end
1026
1564
  alias_method :length, :len
1027
1565
 
1028
- # def cast
1029
- # end
1566
+ # Cast between data types.
1567
+ #
1568
+ # @param dtype [Symbol]
1569
+ # DataType to cast to
1570
+ # @param strict [Boolean]
1571
+ # Throw an error if a cast could not be done for instance due to an overflow
1572
+ #
1573
+ # @return [Series]
1574
+ #
1575
+ # @example
1576
+ # s = Polars::Series.new("a", [true, false, true])
1577
+ # s.cast(:u32)
1578
+ # # =>
1579
+ # # shape: (3,)
1580
+ # # Series: 'a' [u32]
1581
+ # # [
1582
+ # # 1
1583
+ # # 0
1584
+ # # 1
1585
+ # # ]
1586
+ def cast(dtype, strict: true)
1587
+ super
1588
+ end
1030
1589
 
1031
1590
  # def to_physical
1032
1591
  # end
@@ -1054,8 +1613,24 @@ module Polars
1054
1613
  in_place ? self : Utils.wrap_s(opt_s)
1055
1614
  end
1056
1615
 
1057
- # def reverse
1058
- # end
1616
+ # Return Series in reverse order.
1617
+ #
1618
+ # @return [Series]
1619
+ #
1620
+ # @example
1621
+ # s = Polars::Series.new("a", [1, 2, 3], dtype: :i8)
1622
+ # s.reverse
1623
+ # # =>
1624
+ # # shape: (3,)
1625
+ # # Series: 'a' [i8]
1626
+ # # [
1627
+ # # 3
1628
+ # # 2
1629
+ # # 1
1630
+ # # ]
1631
+ def reverse
1632
+ super
1633
+ end
1059
1634
 
1060
1635
  # Check if this Series datatype is numeric.
1061
1636
  #
@@ -1132,19 +1707,143 @@ module Polars
1132
1707
  # def set
1133
1708
  # end
1134
1709
 
1135
- # def set_at_idx
1136
- # end
1710
+ # Set values at the index locations.
1711
+ #
1712
+ # @param idx [Object]
1713
+ # Integers representing the index locations.
1714
+ # @param value [Object]
1715
+ # Replacement values.
1716
+ #
1717
+ # @return [Series]
1718
+ #
1719
+ # @example
1720
+ # s = Polars::Series.new("a", [1, 2, 3])
1721
+ # s.set_at_idx(1, 10)
1722
+ # # =>
1723
+ # # shape: (3,)
1724
+ # # Series: 'a' [i64]
1725
+ # # [
1726
+ # # 1
1727
+ # # 10
1728
+ # # 3
1729
+ # # ]
1730
+ def set_at_idx(idx, value)
1731
+ if idx.is_a?(Integer)
1732
+ idx = [idx]
1733
+ end
1734
+ if idx.length == 0
1735
+ return self
1736
+ end
1137
1737
 
1138
- # def cleared
1139
- # end
1738
+ idx = Series.new("", idx)
1739
+ if value.is_a?(Integer) || value.is_a?(Float) || Utils.bool?(value) || value.is_a?(String) || value.nil?
1740
+ value = Series.new("", [value])
1741
+
1742
+ # if we need to set more than a single value, we extend it
1743
+ if idx.length > 0
1744
+ value = value.extend_constant(value[0], idx.length - 1)
1745
+ end
1746
+ elsif !value.is_a?(Series)
1747
+ value = Series.new("", value)
1748
+ end
1749
+ _s.set_at_idx(idx._s, value._s)
1750
+ self
1751
+ end
1752
+
1753
+ # Create an empty copy of the current Series.
1754
+ #
1755
+ # The copy has identical name/dtype but no data.
1756
+ #
1757
+ # @return [Series]
1758
+ #
1759
+ # @example
1760
+ # s = Polars::Series.new("a", [nil, true, false])
1761
+ # s.cleared
1762
+ # # =>
1763
+ # # shape: (0,)
1764
+ # # Series: 'a' [bool]
1765
+ # # [
1766
+ # # ]
1767
+ def cleared
1768
+ len > 0 ? limit(0) : clone
1769
+ end
1140
1770
 
1141
1771
  # clone handled by initialize_copy
1142
1772
 
1143
- # def fill_nan
1144
- # end
1773
+ # Fill floating point NaN value with a fill value.
1774
+ #
1775
+ # @param fill_value [Object]
1776
+ # Value used to fill nan values.
1777
+ #
1778
+ # @return [Series]
1779
+ #
1780
+ # @example
1781
+ # s = Polars::Series.new("a", [1.0, 2.0, 3.0, Float::NAN])
1782
+ # s.fill_nan(0)
1783
+ # # =>
1784
+ # # shape: (4,)
1785
+ # # Series: 'a' [f64]
1786
+ # # [
1787
+ # # 1.0
1788
+ # # 2.0
1789
+ # # 3.0
1790
+ # # 0.0
1791
+ # # ]
1792
+ def fill_nan(fill_value)
1793
+ super
1794
+ end
1145
1795
 
1146
- # def fill_null
1147
- # end
1796
+ # Fill null values using the specified value or strategy.
1797
+ #
1798
+ # @param value [Object]
1799
+ # Value used to fill null values.
1800
+ # @param strategy [nil, "forward", "backward", "min", "max", "mean", "zero", "one"]
1801
+ # Strategy used to fill null values.
1802
+ # @param limit
1803
+ # Number of consecutive null values to fill when using the "forward" or
1804
+ # "backward" strategy.
1805
+ #
1806
+ # @return [Series]
1807
+ #
1808
+ # @example
1809
+ # s = Polars::Series.new("a", [1, 2, 3, nil])
1810
+ # s.fill_null(strategy: "forward")
1811
+ # # =>
1812
+ # # shape: (4,)
1813
+ # # Series: 'a' [i64]
1814
+ # # [
1815
+ # # 1
1816
+ # # 2
1817
+ # # 3
1818
+ # # 3
1819
+ # # ]
1820
+ #
1821
+ # @example
1822
+ # s.fill_null(strategy: "min")
1823
+ # # =>
1824
+ # # shape: (4,)
1825
+ # # Series: 'a' [i64]
1826
+ # # [
1827
+ # # 1
1828
+ # # 2
1829
+ # # 3
1830
+ # # 1
1831
+ # # ]
1832
+ #
1833
+ # @example
1834
+ # s = Polars::Series.new("b", ["x", nil, "z"])
1835
+ # s.fill_null(Polars.lit(""))
1836
+ # # =>
1837
+ # # shape: (3,)
1838
+ # # Series: 'b' [str]
1839
+ # # [
1840
+ # # "x"
1841
+ # # ""
1842
+ # # "z"
1843
+ # # ]
1844
+ def fill_null(value = nil, strategy: nil, limit: nil)
1845
+ super
1846
+ end
1148
1847
 
1149
1848
  # Rounds down to the nearest integer value.
1150
1849
  #
@@ -1174,99 +1873,410 @@ module Polars
1174
1873
  # @return [Series]
1175
1874
  #
1176
1875
  # @example
1177
- # s = Polars::Series.new("a", [1.12345, 2.56789, 3.901234])
1178
- # s.ceil
1876
+ # s = Polars::Series.new("a", [1.12345, 2.56789, 3.901234])
1877
+ # s.ceil
1878
+ # # =>
1879
+ # # shape: (3,)
1880
+ # # Series: 'a' [f64]
1881
+ # # [
1882
+ # # 2.0
1883
+ # # 3.0
1884
+ # # 4.0
1885
+ # # ]
1886
+ def ceil
1887
+ super
1888
+ end
1889
+
1890
+ # Round underlying floating point data by `decimals` digits.
1891
+ #
1892
+ # @param decimals [Integer]
1893
+ # number of decimals to round by.
1894
+ #
1895
+ # @return [Series]
1896
+ #
1897
+ # @example
1898
+ # s = Polars::Series.new("a", [1.12345, 2.56789, 3.901234])
1899
+ # s.round(2)
1900
+ # # =>
1901
+ # # shape: (3,)
1902
+ # # Series: 'a' [f64]
1903
+ # # [
1904
+ # # 1.12
1905
+ # # 2.57
1906
+ # # 3.9
1907
+ # # ]
1908
+ def round(decimals = 0)
1909
+ super
1910
+ end
1911
+
1912
+ # def dot
1913
+ # end
1914
+
1915
+ # Compute the most occurring value(s).
1916
+ #
1917
+ # Can return multiple Values.
1918
+ #
1919
+ # @return [Series]
1920
+ #
1921
+ # @example
1922
+ # s = Polars::Series.new("a", [1, 2, 2, 3])
1923
+ # s.mode
1924
+ # # =>
1925
+ # # shape: (1,)
1926
+ # # Series: 'a' [i64]
1927
+ # # [
1928
+ # # 2
1929
+ # # ]
1930
+ def mode
1931
+ super
1932
+ end
1933
+
1934
+ # Compute the element-wise indication of the sign.
1935
+ #
1936
+ # @return [Series]
1937
+ #
1938
+ # @example
1939
+ # s = Polars::Series.new("a", [-9.0, -0.0, 0.0, 4.0, nil])
1940
+ # s.sign
1941
+ # # =>
1942
+ # # shape: (5,)
1943
+ # # Series: 'a' [i64]
1944
+ # # [
1945
+ # # -1
1946
+ # # 0
1947
+ # # 0
1948
+ # # 1
1949
+ # # null
1950
+ # # ]
1951
+ def sign
1952
+ super
1953
+ end
1954
+
1955
+ # Compute the element-wise value for the sine.
1956
+ #
1957
+ # @return [Series]
1958
+ #
1959
+ # @example
1960
+ # s = Polars::Series.new("a", [0.0, Math::PI / 2.0, Math::PI])
1961
+ # s.sin
1962
+ # # =>
1963
+ # # shape: (3,)
1964
+ # # Series: 'a' [f64]
1965
+ # # [
1966
+ # # 0.0
1967
+ # # 1.0
1968
+ # # 1.2246e-16
1969
+ # # ]
1970
+ def sin
1971
+ super
1972
+ end
1973
+
1974
+ # Compute the element-wise value for the cosine.
1975
+ #
1976
+ # @return [Series]
1977
+ #
1978
+ # @example
1979
+ # s = Polars::Series.new("a", [0.0, Math::PI / 2.0, Math::PI])
1980
+ # s.cos
1981
+ # # =>
1982
+ # # shape: (3,)
1983
+ # # Series: 'a' [f64]
1984
+ # # [
1985
+ # # 1.0
1986
+ # # 6.1232e-17
1987
+ # # -1.0
1988
+ # # ]
1989
+ def cos
1990
+ super
1991
+ end
1992
+
1993
+ # Compute the element-wise value for the tangent.
1994
+ #
1995
+ # @return [Series]
1996
+ #
1997
+ # @example
1998
+ # s = Polars::Series.new("a", [0.0, Math::PI / 2.0, Math::PI])
1999
+ # s.tan
2000
+ # # =>
2001
+ # # shape: (3,)
2002
+ # # Series: 'a' [f64]
2003
+ # # [
2004
+ # # 0.0
2005
+ # # 1.6331e16
2006
+ # # -1.2246e-16
2007
+ # # ]
2008
+ def tan
2009
+ super
2010
+ end
2011
+
2012
+ # Compute the element-wise value for the inverse sine.
2013
+ #
2014
+ # @return [Series]
2015
+ #
2016
+ # @example
2017
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2018
+ # s.arcsin
2019
+ # # =>
2020
+ # # shape: (3,)
2021
+ # # Series: 'a' [f64]
2022
+ # # [
2023
+ # # 1.570796
2024
+ # # 0.0
2025
+ # # -1.570796
2026
+ # # ]
2027
+ def arcsin
2028
+ super
2029
+ end
2030
+
2031
+ # Compute the element-wise value for the inverse cosine.
2032
+ #
2033
+ # @return [Series]
2034
+ #
2035
+ # @example
2036
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2037
+ # s.arccos
2038
+ # # =>
2039
+ # # shape: (3,)
2040
+ # # Series: 'a' [f64]
2041
+ # # [
2042
+ # # 0.0
2043
+ # # 1.570796
2044
+ # # 3.141593
2045
+ # # ]
2046
+ def arccos
2047
+ super
2048
+ end
2049
+
2050
+ # Compute the element-wise value for the inverse tangent.
2051
+ #
2052
+ # @return [Series]
2053
+ #
2054
+ # @example
2055
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2056
+ # s.arctan
2057
+ # # =>
2058
+ # # shape: (3,)
2059
+ # # Series: 'a' [f64]
2060
+ # # [
2061
+ # # 0.785398
2062
+ # # 0.0
2063
+ # # -0.785398
2064
+ # # ]
2065
+ def arctan
2066
+ super
2067
+ end
2068
+
2069
+ # Compute the element-wise value for the inverse hyperbolic sine.
2070
+ #
2071
+ # @return [Series]
2072
+ #
2073
+ # @example
2074
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2075
+ # s.arcsinh
2076
+ # # =>
2077
+ # # shape: (3,)
2078
+ # # Series: 'a' [f64]
2079
+ # # [
2080
+ # # 0.881374
2081
+ # # 0.0
2082
+ # # -0.881374
2083
+ # # ]
2084
+ def arcsinh
2085
+ super
2086
+ end
2087
+
2088
+ # Compute the element-wise value for the inverse hyperbolic cosine.
2089
+ #
2090
+ # @return [Series]
2091
+ #
2092
+ # @example
2093
+ # s = Polars::Series.new("a", [5.0, 1.0, 0.0, -1.0])
2094
+ # s.arccosh
2095
+ # # =>
2096
+ # # shape: (4,)
2097
+ # # Series: 'a' [f64]
2098
+ # # [
2099
+ # # 2.292432
2100
+ # # 0.0
2101
+ # # NaN
2102
+ # # NaN
2103
+ # # ]
2104
+ def arccosh
2105
+ super
2106
+ end
2107
+
2108
+ # Compute the element-wise value for the inverse hyperbolic tangent.
2109
+ #
2110
+ # @return [Series]
2111
+ #
2112
+ # @example
2113
+ # s = Polars::Series.new("a", [2.0, 1.0, 0.5, 0.0, -0.5, -1.0, -1.1])
2114
+ # s.arctanh
2115
+ # # =>
2116
+ # # shape: (7,)
2117
+ # # Series: 'a' [f64]
2118
+ # # [
2119
+ # # NaN
2120
+ # # inf
2121
+ # # 0.549306
2122
+ # # 0.0
2123
+ # # -0.549306
2124
+ # # -inf
2125
+ # # NaN
2126
+ # # ]
2127
+ def arctanh
2128
+ super
2129
+ end
2130
+
2131
+ # Compute the element-wise value for the hyperbolic sine.
2132
+ #
2133
+ # @return [Series]
2134
+ #
2135
+ # @example
2136
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2137
+ # s.sinh
2138
+ # # =>
2139
+ # # shape: (3,)
2140
+ # # Series: 'a' [f64]
2141
+ # # [
2142
+ # # 1.175201
2143
+ # # 0.0
2144
+ # # -1.175201
2145
+ # # ]
2146
+ def sinh
2147
+ super
2148
+ end
2149
+
2150
+ # Compute the element-wise value for the hyperbolic cosine.
2151
+ #
2152
+ # @return [Series]
2153
+ #
2154
+ # @example
2155
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2156
+ # s.cosh
2157
+ # # =>
2158
+ # # shape: (3,)
2159
+ # # Series: 'a' [f64]
2160
+ # # [
2161
+ # # 1.543081
2162
+ # # 1.0
2163
+ # # 1.543081
2164
+ # # ]
2165
+ def cosh
2166
+ super
2167
+ end
2168
+
2169
+ # Compute the element-wise value for the hyperbolic tangent.
2170
+ #
2171
+ # @return [Series]
2172
+ #
2173
+ # @example
2174
+ # s = Polars::Series.new("a", [1.0, 0.0, -1.0])
2175
+ # s.tanh
2176
+ # # =>
2177
+ # # shape: (3,)
2178
+ # # Series: 'a' [f64]
2179
+ # # [
2180
+ # # 0.761594
2181
+ # # 0.0
2182
+ # # -0.761594
2183
+ # # ]
2184
+ def tanh
2185
+ super
2186
+ end
2187
+
2188
+ # def apply
2189
+ # end
2190
+
2191
+ # Shift the values by a given period.
2192
+ #
2193
+ # @param periods [Integer]
2194
+ # Number of places to shift (may be negative).
2195
+ #
2196
+ # @return [Series]
2197
+ #
2198
+ # @example
2199
+ # s = Polars::Series.new("a", [1, 2, 3])
2200
+ # s.shift(1)
2201
+ # # =>
2202
+ # # shape: (3,)
2203
+ # # Series: 'a' [i64]
2204
+ # # [
2205
+ # # null
2206
+ # # 1
2207
+ # # 2
2208
+ # # ]
2209
+ #
2210
+ # @example
2211
+ # s.shift(-1)
1179
2212
  # # =>
1180
2213
  # # shape: (3,)
1181
- # # Series: 'a' [f64]
2214
+ # # Series: 'a' [i64]
1182
2215
  # # [
1183
- # # 2.0
1184
- # # 3.0
1185
- # # 4.0
2216
+ # # 2
2217
+ # # 3
2218
+ # # null
1186
2219
  # # ]
1187
- def ceil
1188
- Utils.wrap_s(_s.ceil)
2220
+ def shift(periods = 1)
2221
+ super
1189
2222
  end
1190
2223
 
1191
- # Round underlying floating point data by `decimals` digits.
2224
+ # Shift the values by a given period and fill the resulting null values.
1192
2225
  #
1193
- # @param decimals [Integer]
1194
- # number of decimals to round by.
2226
+ # @param periods [Integer]
2227
+ # Number of places to shift (may be negative).
2228
+ # @param fill_value [Object]
2229
+ # Fill None values with the result of this expression.
2230
+ #
2231
+ # @return [Series]
2232
+ def shift_and_fill(periods, fill_value)
2233
+ super
2234
+ end
2235
+
2236
+ # Take values from self or other based on the given mask.
2237
+ #
2238
+ # Where mask evaluates true, take values from self. Where mask evaluates false,
2239
+ # take values from other.
2240
+ #
2241
+ # @param mask [Series]
2242
+ # Boolean Series.
2243
+ # @param other [Series]
2244
+ # Series of same type.
1195
2245
  #
1196
2246
  # @return [Series]
1197
2247
  #
1198
2248
  # @example
1199
- # s = Polars::Series.new("a", [1.12345, 2.56789, 3.901234])
1200
- # s.round(2)
2249
+ # s1 = Polars::Series.new([1, 2, 3, 4, 5])
2250
+ # s2 = Polars::Series.new([5, 4, 3, 2, 1])
2251
+ # s1.zip_with(s1 < s2, s2)
1201
2252
  # # =>
1202
- # # shape: (3,)
1203
- # # Series: 'a' [f64]
2253
+ # # shape: (5,)
2254
+ # # Series: '' [i64]
1204
2255
  # # [
1205
- # # 1.12
1206
- # # 2.57
1207
- # # 3.9
2256
+ # # 1
2257
+ # # 2
2258
+ # # 3
2259
+ # # 2
2260
+ # # 1
1208
2261
  # # ]
1209
- def round(decimals = 0)
1210
- Utils.wrap_s(_s.round(decimals))
2262
+ #
2263
+ # @example
2264
+ # mask = Polars::Series.new([true, false, true, false, true])
2265
+ # s1.zip_with(mask, s2)
2266
+ # # =>
2267
+ # # shape: (5,)
2268
+ # # Series: '' [i64]
2269
+ # # [
2270
+ # # 1
2271
+ # # 4
2272
+ # # 3
2273
+ # # 2
2274
+ # # 5
2275
+ # # ]
2276
+ def zip_with(mask, other)
2277
+ Utils.wrap_s(_s.zip_with(mask._s, other._s))
1211
2278
  end
1212
2279
 
1213
- # def dot
1214
- # end
1215
-
1216
- # def mode
1217
- # end
1218
-
1219
- # def sign
1220
- # end
1221
-
1222
- # def sin
1223
- # end
1224
-
1225
- # def cos
1226
- # end
1227
-
1228
- # def tan
1229
- # end
1230
-
1231
- # def arcsin
1232
- # end
1233
-
1234
- # def arccos
1235
- # end
1236
-
1237
- # def arctan
1238
- # end
1239
-
1240
- # def arcsinh
1241
- # end
1242
-
1243
- # def arccosh
1244
- # end
1245
-
1246
- # def arctanh
1247
- # end
1248
-
1249
- # def sinh
1250
- # end
1251
-
1252
- # def cosh
1253
- # end
1254
-
1255
- # def tanh
1256
- # end
1257
-
1258
- # def apply
1259
- # end
1260
-
1261
- # def shift
1262
- # end
1263
-
1264
- # def shift_and_fill
1265
- # end
1266
-
1267
- # def zip_with
1268
- # end
1269
-
1270
2280
  # def rolling_min
1271
2281
  # end
1272
2282
 
@@ -1354,50 +2364,212 @@ module Polars
1354
2364
  _s.n_unique
1355
2365
  end
1356
2366
 
1357
- # def shrink_to_fit
1358
- # end
2367
+ # Shrink Series memory usage.
2368
+ #
2369
+ # Shrinks the underlying array capacity to exactly fit the actual data.
2370
+ # (Note that this function does not change the Series data type).
2371
+ #
2372
+ # @return [Series]
2373
+ def shrink_to_fit(in_place: false)
2374
+ if in_place
2375
+ _s.shrink_to_fit
2376
+ self
2377
+ else
2378
+ series = clone
2379
+ series._s.shrink_to_fit
2380
+ series
2381
+ end
2382
+ end
1359
2383
 
1360
2384
  # def _hash
1361
2385
  # end
1362
2386
 
1363
- # def reinterpret
1364
- # end
2387
+ # Reinterpret the underlying bits as a signed/unsigned integer.
2388
+ #
2389
+ # This operation is only allowed for 64bit integers. For lower bits integers,
2390
+ # you can safely use that cast operation.
2391
+ #
2392
+ # @param signed [Boolean]
2393
+ # If true, reinterpret as `:i64`. Otherwise, reinterpret as `:u64`.
2394
+ #
2395
+ # @return [Series]
2396
+ def reinterpret(signed: true)
2397
+ super
2398
+ end
1365
2399
 
1366
- # def interpolate
1367
- # end
2400
+ # Interpolate intermediate values. The interpolation method is linear.
2401
+ #
2402
+ # @return [Series]
2403
+ #
2404
+ # @example
2405
+ # s = Polars::Series.new("a", [1, 2, nil, nil, 5])
2406
+ # s.interpolate
2407
+ # # =>
2408
+ # # shape: (5,)
2409
+ # # Series: 'a' [i64]
2410
+ # # [
2411
+ # # 1
2412
+ # # 2
2413
+ # # 3
2414
+ # # 4
2415
+ # # 5
2416
+ # # ]
2417
+ def interpolate
2418
+ super
2419
+ end
1368
2420
 
1369
- # def abs
1370
- # end
2421
+ # Compute absolute values.
2422
+ #
2423
+ # @return [Series]
2424
+ def abs
2425
+ super
2426
+ end
1371
2427
 
1372
2428
  # def rank
1373
2429
  # end
1374
2430
 
1375
- # def diff
1376
- # end
2431
+ # Calculate the n-th discrete difference.
2432
+ #
2433
+ # @param n [Integer]
2434
+ # Number of slots to shift.
2435
+ # @param null_behavior ["ignore", "drop"]
2436
+ # How to handle null values.
2437
+ #
2438
+ # @return [Series]
2439
+ def diff(n: 1, null_behavior: "ignore")
2440
+ super
2441
+ end
1377
2442
 
1378
2443
  # def pct_change
1379
2444
  # end
1380
2445
 
1381
- # def skew
1382
- # end
2446
+ # Compute the sample skewness of a data set.
2447
+ #
2448
+ # For normally distributed data, the skewness should be about zero. For
2449
+ # unimodal continuous distributions, a skewness value greater than zero means
2450
+ # that there is more weight in the right tail of the distribution. The
2451
+ # function `skewtest` can be used to determine if the skewness value
2452
+ # is close enough to zero, statistically speaking.
2453
+ #
2454
+ # @param bias [Boolean]
2455
+ # If `false`, the calculations are corrected for statistical bias.
2456
+ #
2457
+ # @return [Float, nil]
2458
+ def skew(bias: true)
2459
+ _s.skew(bias)
2460
+ end
1383
2461
 
1384
- # def kurtosis
1385
- # end
2462
+ # Compute the kurtosis (Fisher or Pearson) of a dataset.
2463
+ #
2464
+ # Kurtosis is the fourth central moment divided by the square of the
2465
+ # variance. If Fisher's definition is used, then 3.0 is subtracted from
2466
+ # the result to give 0.0 for a normal distribution.
2467
+ # If bias is false, then the kurtosis is calculated using k statistics to
2468
+ # eliminate bias coming from biased moment estimators
2469
+ #
2470
+ # @param fisher [Boolean]
2471
+ # If `true`, Fisher's definition is used (normal ==> 0.0). If `false`,
2472
+ # Pearson's definition is used (normal ==> 3.0).
2473
+ # @param bias [Boolean]
2474
+ # If `false`, the calculations are corrected for statistical bias.
2475
+ #
2476
+ # @return [Float, nil]
2477
+ def kurtosis(fisher: true, bias: true)
2478
+ _s.kurtosis(fisher, bias)
2479
+ end
1386
2480
 
1387
- # def clip
1388
- # end
2481
+ # Clip (limit) the values in an array to a `min` and `max` boundary.
2482
+ #
2483
+ # Only works for numerical types.
2484
+ #
2485
+ # If you want to clip other dtypes, consider writing a "when, then, otherwise"
2486
+ # expression. See {#when} for more information.
2487
+ #
2488
+ # @param min_val [Numeric]
2489
+ # Minimum value.
2490
+ # @param max_val [Numeric]
2491
+ # Maximum value.
2492
+ #
2493
+ # @return [Series]
2494
+ #
2495
+ # @example
2496
+ # s = Polars::Series.new("foo", [-50, 5, nil, 50])
2497
+ # s.clip(1, 10)
2498
+ # # =>
2499
+ # # shape: (4,)
2500
+ # # Series: 'foo' [i64]
2501
+ # # [
2502
+ # # 1
2503
+ # # 5
2504
+ # # null
2505
+ # # 10
2506
+ # # ]
2507
+ def clip(min_val, max_val)
2508
+ super
2509
+ end
1389
2510
 
1390
- # def clip_min
1391
- # end
2511
+ # Clip (limit) the values in an array to a `min` boundary.
2512
+ #
2513
+ # Only works for numerical types.
2514
+ #
2515
+ # If you want to clip other dtypes, consider writing a "when, then, otherwise"
2516
+ # expression. See {#when} for more information.
2517
+ #
2518
+ # @param min_val [Numeric]
2519
+ # Minimum value.
2520
+ #
2521
+ # @return [Series]
2522
+ def clip_min(min_val)
2523
+ super
2524
+ end
1392
2525
 
1393
- # def clip_max
1394
- # end
2526
+ # Clip (limit) the values in an array to a `max` boundary.
2527
+ #
2528
+ # Only works for numerical types.
2529
+ #
2530
+ # If you want to clip other dtypes, consider writing a "when, then, otherwise"
2531
+ # expression. See {#when} for more information.
2532
+ #
2533
+ # @param max_val [Numeric]
2534
+ # Maximum value.
2535
+ #
2536
+ # @return [Series]
2537
+ def clip_max(max_val)
2538
+ super
2539
+ end
1395
2540
 
1396
- # def reshape
1397
- # end
2541
+ # Reshape this Series to a flat Series or a Series of Lists.
2542
+ #
2543
+ # @param dims [Array]
2544
+ # Tuple of the dimension sizes. If a -1 is used in any of the dimensions, that
2545
+ # dimension is inferred.
2546
+ #
2547
+ # @return [Series]
2548
+ def reshape(dims)
2549
+ super
2550
+ end
1398
2551
 
1399
- # def shuffle
1400
- # end
2552
+ # Shuffle the contents of this Series.
2553
+ #
2554
+ # @param seed [Integer, nil]
2555
+ # Seed for the random number generator.
2556
+ #
2557
+ # @return [Series]
2558
+ #
2559
+ # @example
2560
+ # s = Polars::Series.new("a", [1, 2, 3])
2561
+ # s.shuffle(seed: 1)
2562
+ # # =>
2563
+ # # shape: (3,)
2564
+ # # Series: 'a' [i64]
2565
+ # # [
2566
+ # # 2
2567
+ # # 1
2568
+ # # 3
2569
+ # # ]
2570
+ def shuffle(seed: nil)
2571
+ super
2572
+ end
1401
2573
 
1402
2574
  # def ewm_mean
1403
2575
  # end
@@ -1408,8 +2580,32 @@ module Polars
1408
2580
  # def ewm_var
1409
2581
  # end
1410
2582
 
1411
- # def extend_constant
1412
- # end
2583
+ # Extend the Series with given number of values.
2584
+ #
2585
+ # @param value [Object]
2586
+ # The value to extend the Series with. This value may be `nil` to fill with
2587
+ # nulls.
2588
+ # @param n [Integer]
2589
+ # The number of values to extend.
2590
+ #
2591
+ # @return [Series]
2592
+ #
2593
+ # @example
2594
+ # s = Polars::Series.new("a", [1, 2, 3])
2595
+ # s.extend_constant(99, 2)
2596
+ # # =>
2597
+ # # shape: (5,)
2598
+ # # Series: 'a' [i64]
2599
+ # # [
2600
+ # # 1
2601
+ # # 2
2602
+ # # 3
2603
+ # # 99
2604
+ # # 99
2605
+ # # ]
2606
+ def extend_constant(value, n)
2607
+ super
2608
+ end
1413
2609
 
1414
2610
  # Flags the Series as sorted.
1415
2611
  #
@@ -1432,11 +2628,22 @@ module Polars
1432
2628
  Utils.wrap_s(_s.set_sorted(reverse))
1433
2629
  end
1434
2630
 
1435
- # def new_from_index
1436
- # end
2631
+ # Create a new Series filled with values from the given index.
2632
+ #
2633
+ # @return [Series]
2634
+ def new_from_index(index, length)
2635
+ Utils.wrap_s(_s.new_from_index(index, length))
2636
+ end
1437
2637
 
1438
- # def shrink_dtype
1439
- # end
2638
+ # Shrink numeric columns to the minimal required datatype.
2639
+ #
2640
+ # Shrink to the dtype needed to fit the extrema of this Series.
2641
+ # This can be used to reduce memory pressure.
2642
+ #
2643
+ # @return [Series]
2644
+ def shrink_dtype
2645
+ super
2646
+ end
1440
2647
 
1441
2648
  # def arr
1442
2649
  # end
@@ -1460,8 +2667,47 @@ module Polars
1460
2667
  self._s = _s._clone
1461
2668
  end
1462
2669
 
2670
+ def coerce(other)
2671
+ if other.is_a?(Numeric)
2672
+ # TODO improve
2673
+ series = to_frame.select(Polars.lit(other)).to_series
2674
+ [series, self]
2675
+ else
2676
+ raise TypeError, "#{self.class} can't be coerced into #{other.class}"
2677
+ end
2678
+ end
2679
+
2680
+ def _comp(other, op)
2681
+ if other.is_a?(Series)
2682
+ return Utils.wrap_s(_s.send(op, other._s))
2683
+ end
2684
+
2685
+ if dtype == :str
2686
+ raise Todo
2687
+ end
2688
+ Utils.wrap_s(_s.send("#{op}_#{dtype}", other))
2689
+ end
2690
+
2691
+ def _arithmetic(other, op)
2692
+ if other.is_a?(Expr)
2693
+ other = to_frame.select(other).to_series
2694
+ end
2695
+ if other.is_a?(Series)
2696
+ return Utils.wrap_s(_s.send(op, other._s))
2697
+ end
2698
+
2699
+ raise Todo
2700
+ end
2701
+
2702
+ def series_to_rbseries(name, values)
2703
+ # should not be in-place?
2704
+ values.rename(name, in_place: true)
2705
+ values._s
2706
+ end
2707
+
1463
2708
  def sequence_to_rbseries(name, values, dtype: nil, strict: true, dtype_if_empty: nil)
1464
2709
  ruby_dtype = nil
2710
+ nested_dtype = nil
1465
2711
 
1466
2712
  if (values.nil? || values.empty?) && dtype.nil?
1467
2713
  if dtype_if_empty
@@ -1470,7 +2716,7 @@ module Polars
1470
2716
  dtype = dtype_if_empty
1471
2717
  else
1472
2718
  # default to Float32 type
1473
- dtype = "f32"
2719
+ dtype = :f32
1474
2720
  end
1475
2721
  end
1476
2722
 
@@ -1479,8 +2725,7 @@ module Polars
1479
2725
  rb_temporal_types << DateTime if defined?(DateTime)
1480
2726
  rb_temporal_types << Time if defined?(Time)
1481
2727
 
1482
- # _get_first_non_none
1483
- value = values.find { |v| !v.nil? }
2728
+ value = _get_first_non_none(values)
1484
2729
 
1485
2730
  if !dtype.nil? && Utils.is_polars_dtype(dtype) && ruby_dtype.nil?
1486
2731
  constructor = polars_type_to_constructor(dtype)
@@ -1504,6 +2749,21 @@ module Polars
1504
2749
  # dtype = rb_type_to_dtype(dtype)
1505
2750
  # end
1506
2751
 
2752
+ if ruby_dtype == Date
2753
+ RbSeries.new_opt_date(name, values, strict)
2754
+ else
2755
+ raise Todo
2756
+ end
2757
+ elsif ruby_dtype == Array
2758
+ if nested_dtype.nil?
2759
+ nested_value = _get_first_non_none(value)
2760
+ nested_dtype = nested_value.nil? ? Float : nested_value.class
2761
+ end
2762
+
2763
+ if nested_dtype == Array
2764
+ raise Todo
2765
+ end
2766
+
1507
2767
  raise Todo
1508
2768
  else
1509
2769
  constructor = rb_type_to_constructor(value.class)
@@ -1547,5 +2807,9 @@ module Polars
1547
2807
  # RbSeries.method(:new_object)
1548
2808
  raise ArgumentError, "Cannot determine type"
1549
2809
  end
2810
+
2811
+ def _get_first_non_none(values)
2812
+ values.find { |v| !v.nil? }
2813
+ end
1550
2814
  end
1551
2815
  end