polars-df 0.1.2 → 0.1.3

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