polars-df 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/Cargo.lock +337 -381
  4. data/README.md +4 -3
  5. data/ext/polars/Cargo.toml +5 -4
  6. data/ext/polars/src/apply/mod.rs +7 -3
  7. data/ext/polars/src/conversion.rs +171 -63
  8. data/ext/polars/src/dataframe.rs +19 -23
  9. data/ext/polars/src/error.rs +8 -0
  10. data/ext/polars/src/expr/array.rs +15 -0
  11. data/ext/polars/src/expr/general.rs +39 -9
  12. data/ext/polars/src/expr/list.rs +27 -22
  13. data/ext/polars/src/expr/string.rs +10 -9
  14. data/ext/polars/src/expr.rs +1 -0
  15. data/ext/polars/src/functions/lazy.rs +61 -21
  16. data/ext/polars/src/lazyframe.rs +14 -2
  17. data/ext/polars/src/lib.rs +25 -20
  18. data/ext/polars/src/object.rs +1 -1
  19. data/ext/polars/src/rb_modules.rs +4 -0
  20. data/ext/polars/src/series/construction.rs +28 -2
  21. data/ext/polars/src/series.rs +57 -17
  22. data/lib/polars/array_expr.rb +84 -0
  23. data/lib/polars/array_name_space.rb +77 -0
  24. data/lib/polars/batched_csv_reader.rb +1 -1
  25. data/lib/polars/data_frame.rb +91 -49
  26. data/lib/polars/data_types.rb +163 -29
  27. data/lib/polars/date_time_name_space.rb +17 -3
  28. data/lib/polars/expr.rb +76 -69
  29. data/lib/polars/functions.rb +0 -1
  30. data/lib/polars/group_by.rb +1 -22
  31. data/lib/polars/lazy_frame.rb +82 -30
  32. data/lib/polars/lazy_functions.rb +67 -31
  33. data/lib/polars/list_expr.rb +28 -28
  34. data/lib/polars/list_name_space.rb +13 -13
  35. data/lib/polars/rolling_group_by.rb +4 -2
  36. data/lib/polars/series.rb +70 -16
  37. data/lib/polars/string_expr.rb +137 -11
  38. data/lib/polars/string_name_space.rb +137 -22
  39. data/lib/polars/utils.rb +107 -57
  40. data/lib/polars/version.rb +1 -1
  41. data/lib/polars.rb +3 -0
  42. metadata +5 -2
data/lib/polars/expr.rb CHANGED
@@ -362,7 +362,7 @@ module Polars
362
362
  if columns.is_a?(String)
363
363
  columns = [columns]
364
364
  return wrap_expr(_rbexpr.exclude(columns))
365
- elsif !columns.is_a?(Array)
365
+ elsif !columns.is_a?(::Array)
366
366
  columns = [columns]
367
367
  return wrap_expr(_rbexpr.exclude_dtype(columns))
368
368
  end
@@ -820,18 +820,18 @@ module Polars
820
820
  # df.select(Polars.repeat(nil, 3).append(Polars.col("a")).rechunk)
821
821
  # # =>
822
822
  # # shape: (6, 1)
823
- # # ┌─────────┐
824
- # # │ literal
825
- # # │ ---
826
- # # │ i64
827
- # # ╞═════════╡
828
- # # │ null
829
- # # │ null
830
- # # │ null
831
- # # │ 1
832
- # # │ 1
833
- # # │ 2
834
- # # └─────────┘
823
+ # # ┌────────┐
824
+ # # │ repeat
825
+ # # │ ---
826
+ # # │ i64
827
+ # # ╞════════╡
828
+ # # │ null
829
+ # # │ null
830
+ # # │ null
831
+ # # │ 1
832
+ # # │ 1
833
+ # # │ 2
834
+ # # └────────┘
835
835
  def rechunk
836
836
  wrap_expr(_rbexpr.rechunk)
837
837
  end
@@ -1534,10 +1534,10 @@ module Polars
1534
1534
  # # │ two │
1535
1535
  # # └───────┘
1536
1536
  def sort_by(by, reverse: false)
1537
- if !by.is_a?(Array)
1537
+ if !by.is_a?(::Array)
1538
1538
  by = [by]
1539
1539
  end
1540
- if !reverse.is_a?(Array)
1540
+ if !reverse.is_a?(::Array)
1541
1541
  reverse = [reverse]
1542
1542
  end
1543
1543
  by = Utils.selection_to_rbexpr_list(by)
@@ -1578,7 +1578,7 @@ module Polars
1578
1578
  # # │ two ┆ 99 │
1579
1579
  # # └───────┴───────┘
1580
1580
  def take(indices)
1581
- if indices.is_a?(Array)
1581
+ if indices.is_a?(::Array)
1582
1582
  indices_lit = Polars.lit(Series.new("", indices, dtype: :u32))
1583
1583
  else
1584
1584
  indices_lit = Utils.expr_to_lit_or_expr(indices, str_to_lit: false)
@@ -2436,14 +2436,14 @@ module Polars
2436
2436
  # ).sort("group_col")
2437
2437
  # # =>
2438
2438
  # # shape: (2, 3)
2439
- # # ┌───────────┬──────┬─────┐
2440
- # # │ group_col ┆ lt ┆ gte │
2441
- # # │ --- ┆ --- ┆ --- │
2442
- # # │ str ┆ i64 ┆ i64 │
2443
- # # ╞═══════════╪══════╪═════╡
2444
- # # │ g1 ┆ 1 ┆ 2 │
2445
- # # │ g2 ┆ null ┆ 3 │
2446
- # # └───────────┴──────┴─────┘
2439
+ # # ┌───────────┬─────┬─────┐
2440
+ # # │ group_col ┆ lt ┆ gte │
2441
+ # # │ --- ┆ --- ┆ --- │
2442
+ # # │ str ┆ i64 ┆ i64 │
2443
+ # # ╞═══════════╪═════╪═════╡
2444
+ # # │ g1 ┆ 1 ┆ 2 │
2445
+ # # │ g2 ┆ 0 ┆ 3 │
2446
+ # # └───────────┴─────┴─────┘
2447
2447
  def filter(predicate)
2448
2448
  wrap_expr(_rbexpr.filter(predicate._rbexpr))
2449
2449
  end
@@ -2474,14 +2474,14 @@ module Polars
2474
2474
  # ).sort("group_col")
2475
2475
  # # =>
2476
2476
  # # shape: (2, 3)
2477
- # # ┌───────────┬──────┬─────┐
2478
- # # │ group_col ┆ lt ┆ gte │
2479
- # # │ --- ┆ --- ┆ --- │
2480
- # # │ str ┆ i64 ┆ i64 │
2481
- # # ╞═══════════╪══════╪═════╡
2482
- # # │ g1 ┆ 1 ┆ 2 │
2483
- # # │ g2 ┆ null ┆ 3 │
2484
- # # └───────────┴──────┴─────┘
2477
+ # # ┌───────────┬─────┬─────┐
2478
+ # # │ group_col ┆ lt ┆ gte │
2479
+ # # │ --- ┆ --- ┆ --- │
2480
+ # # │ str ┆ i64 ┆ i64 │
2481
+ # # ╞═══════════╪═════╪═════╡
2482
+ # # │ g1 ┆ 1 ┆ 2 │
2483
+ # # │ g2 ┆ 0 ┆ 3 │
2484
+ # # └───────────┴─────┴─────┘
2485
2485
  def where(predicate)
2486
2486
  filter(predicate)
2487
2487
  end
@@ -2616,25 +2616,23 @@ module Polars
2616
2616
  # @return [Expr]
2617
2617
  #
2618
2618
  # @example
2619
- # df = Polars::DataFrame.new({"foo" => ["hello", "world"]})
2620
- # df.select(Polars.col("foo").flatten)
2621
- # # =>
2622
- # # shape: (10, 1)
2623
- # # ┌─────┐
2624
- # # │ foo │
2625
- # # │ --- │
2626
- # # │ str │
2627
- # # ╞═════╡
2628
- # # │ h │
2629
- # # │ e
2630
- # # │ l
2631
- # # │ l
2632
- # # │ … │
2633
- # # │ o
2634
- # # │ r
2635
- # # │ l │
2636
- # # │ d │
2637
- # # └─────┘
2619
+ # df = Polars::DataFrame.new(
2620
+ # {
2621
+ # "group" => ["a", "b", "b"],
2622
+ # "values" => [[1, 2], [2, 3], [4]]
2623
+ # }
2624
+ # )
2625
+ # df.groupby("group").agg(Polars.col("values").flatten)
2626
+ # # =>
2627
+ # # shape: (2, 2)
2628
+ # # ┌───────┬───────────┐
2629
+ # # │ group ┆ values
2630
+ # # │ --- ┆ ---
2631
+ # # │ str ┆ list[i64]
2632
+ # # ╞═══════╪═══════════╡
2633
+ # # │ a ┆ [1, 2]
2634
+ # # │ b ┆ [2, 3, 4]
2635
+ # # └───────┴───────────┘
2638
2636
  def flatten
2639
2637
  wrap_expr(_rbexpr.explode)
2640
2638
  end
@@ -2798,7 +2796,7 @@ module Polars
2798
2796
  # # │ false │
2799
2797
  # # └──────────┘
2800
2798
  def is_in(other)
2801
- if other.is_a?(Array)
2799
+ if other.is_a?(::Array)
2802
2800
  if other.length == 0
2803
2801
  other = Polars.lit(nil)
2804
2802
  else
@@ -3502,14 +3500,15 @@ module Polars
3502
3500
  min_periods: nil,
3503
3501
  center: false,
3504
3502
  by: nil,
3505
- closed: "left"
3503
+ closed: "left",
3504
+ ddof: 1
3506
3505
  )
3507
3506
  window_size, min_periods = _prepare_rolling_window_args(
3508
3507
  window_size, min_periods
3509
3508
  )
3510
3509
  wrap_expr(
3511
3510
  _rbexpr.rolling_std(
3512
- window_size, weights, min_periods, center, by, closed
3511
+ window_size, weights, min_periods, center, by, closed, ddof
3513
3512
  )
3514
3513
  )
3515
3514
  end
@@ -3591,14 +3590,15 @@ module Polars
3591
3590
  min_periods: nil,
3592
3591
  center: false,
3593
3592
  by: nil,
3594
- closed: "left"
3593
+ closed: "left",
3594
+ ddof: 1
3595
3595
  )
3596
3596
  window_size, min_periods = _prepare_rolling_window_args(
3597
3597
  window_size, min_periods
3598
3598
  )
3599
3599
  wrap_expr(
3600
3600
  _rbexpr.rolling_var(
3601
- window_size, weights, min_periods, center, by, closed
3601
+ window_size, weights, min_periods, center, by, closed, ddof
3602
3602
  )
3603
3603
  )
3604
3604
  end
@@ -4558,11 +4558,11 @@ module Polars
4558
4558
  # # │ 1 │
4559
4559
  # # │ 3 │
4560
4560
  # # └─────┘
4561
- def shuffle(seed: nil)
4561
+ def shuffle(seed: nil, fixed_seed: false)
4562
4562
  if seed.nil?
4563
4563
  seed = rand(10000)
4564
4564
  end
4565
- wrap_expr(_rbexpr.shuffle(seed))
4565
+ wrap_expr(_rbexpr.shuffle(seed, fixed_seed))
4566
4566
  end
4567
4567
 
4568
4568
  # Sample from this expression.
@@ -4600,21 +4600,22 @@ module Polars
4600
4600
  with_replacement: true,
4601
4601
  shuffle: false,
4602
4602
  seed: nil,
4603
- n: nil
4603
+ n: nil,
4604
+ fixed_seed: false
4604
4605
  )
4605
4606
  if !n.nil? && !frac.nil?
4606
4607
  raise ArgumentError, "cannot specify both `n` and `frac`"
4607
4608
  end
4608
4609
 
4609
4610
  if !n.nil? && frac.nil?
4610
- return wrap_expr(_rbexpr.sample_n(n, with_replacement, shuffle, seed))
4611
+ return wrap_expr(_rbexpr.sample_n(n, with_replacement, shuffle, seed, fixed_seed))
4611
4612
  end
4612
4613
 
4613
4614
  if frac.nil?
4614
4615
  frac = 1.0
4615
4616
  end
4616
4617
  wrap_expr(
4617
- _rbexpr.sample_frac(frac, with_replacement, shuffle, seed)
4618
+ _rbexpr.sample_frac(frac, with_replacement, shuffle, seed, fixed_seed)
4618
4619
  )
4619
4620
  end
4620
4621
 
@@ -4929,8 +4930,8 @@ module Polars
4929
4930
  #
4930
4931
  # Enables downstream code to user fast paths for sorted arrays.
4931
4932
  #
4932
- # @param reverse [Boolean]
4933
- # If the `Series` order is reversed, e.g. descending.
4933
+ # @param descending [Boolean]
4934
+ # Whether the `Series` order is descending.
4934
4935
  #
4935
4936
  # @return [Expr]
4936
4937
  #
@@ -4950,9 +4951,9 @@ module Polars
4950
4951
  # # ╞════════╡
4951
4952
  # # │ 3 │
4952
4953
  # # └────────┘
4953
- # def set_sorted(reverse: false)
4954
- # map { |s| s.set_sorted(reverse) }
4955
- # end
4954
+ def set_sorted(descending: false)
4955
+ wrap_expr(_rbexpr.set_sorted_flag(descending))
4956
+ end
4956
4957
 
4957
4958
  # Aggregate to list.
4958
4959
  #
@@ -4965,7 +4966,7 @@ module Polars
4965
4966
  # "b" => [4, 5, 6]
4966
4967
  # }
4967
4968
  # )
4968
- # df.select(Polars.all.list)
4969
+ # df.select(Polars.all.implode)
4969
4970
  # # =>
4970
4971
  # # shape: (1, 2)
4971
4972
  # # ┌───────────┬───────────┐
@@ -4978,7 +4979,6 @@ module Polars
4978
4979
  def implode
4979
4980
  wrap_expr(_rbexpr.implode)
4980
4981
  end
4981
- alias_method :list, :implode
4982
4982
 
4983
4983
  # Shrink numeric columns to the minimal required datatype.
4984
4984
  #
@@ -5018,10 +5018,17 @@ module Polars
5018
5018
  # Create an object namespace of all list related methods.
5019
5019
  #
5020
5020
  # @return [ListExpr]
5021
- def arr
5021
+ def list
5022
5022
  ListExpr.new(self)
5023
5023
  end
5024
5024
 
5025
+ # Create an object namespace of all array related methods.
5026
+ #
5027
+ # @return [ArrayExpr]
5028
+ def arr
5029
+ ArrayExpr.new(self)
5030
+ end
5031
+
5025
5032
  # Create an object namespace of all binary related methods.
5026
5033
  #
5027
5034
  # @return [BinaryExpr]
@@ -43,7 +43,6 @@ module Polars
43
43
  # # │ i64 ┆ i64 │
44
44
  # # ╞═════╪═════╡
45
45
  # # │ 1 ┆ 3 │
46
- # # ├╌╌╌╌╌┼╌╌╌╌╌┤
47
46
  # # │ 2 ┆ 4 │
48
47
  # # └─────┴─────┘
49
48
  def concat(items, rechunk: true, how: "vertical", parallel: true)
@@ -551,32 +551,11 @@ module Polars
551
551
  agg(Polars.all.median)
552
552
  end
553
553
 
554
- # Aggregate the groups into Series.
555
- #
556
- # @return [DataFrame]
557
- #
558
- # @example
559
- # df = Polars::DataFrame.new({"a" => ["one", "two", "one", "two"], "b" => [1, 2, 3, 4]})
560
- # df.groupby("a", maintain_order: true).agg_list
561
- # # =>
562
- # # shape: (2, 2)
563
- # # ┌─────┬─────────────────┐
564
- # # │ a ┆ b │
565
- # # │ --- ┆ --- │
566
- # # │ str ┆ list[list[i64]] │
567
- # # ╞═════╪═════════════════╡
568
- # # │ one ┆ [[1, 3]] │
569
- # # │ two ┆ [[2, 4]] │
570
- # # └─────┴─────────────────┘
571
- def agg_list
572
- agg(Polars.all.list)
573
- end
574
-
575
554
  # Plot data.
576
555
  #
577
556
  # @return [Vega::LiteChart]
578
557
  def plot(*args, **options)
579
- raise ArgumentError, "Multiple groups not supported" if by.is_a?(Array) && by.size > 1
558
+ raise ArgumentError, "Multiple groups not supported" if by.is_a?(::Array) && by.size > 1
580
559
  # same message as Ruby
581
560
  raise ArgumentError, "unknown keyword: :group" if options.key?(:group)
582
561
 
@@ -4,6 +4,22 @@ module Polars
4
4
  # @private
5
5
  attr_accessor :_ldf
6
6
 
7
+ # Create a new LazyFrame.
8
+ def initialize(data = nil, schema: nil, schema_overrides: nil, orient: nil, infer_schema_length: 100, nan_to_null: false)
9
+ self._ldf = (
10
+ DataFrame.new(
11
+ data,
12
+ schema: schema,
13
+ schema_overrides: schema_overrides,
14
+ orient: orient,
15
+ infer_schema_length: infer_schema_length,
16
+ nan_to_null: nan_to_null
17
+ )
18
+ .lazy
19
+ ._ldf
20
+ )
21
+ end
22
+
7
23
  # @private
8
24
  def self._from_rbldf(rb_ldf)
9
25
  ldf = LazyFrame.allocate
@@ -379,16 +395,16 @@ module Polars
379
395
  # # │ 2 ┆ 7.0 ┆ b │
380
396
  # # │ 1 ┆ 6.0 ┆ a │
381
397
  # # └─────┴─────┴─────┘
382
- def sort(by, reverse: false, nulls_last: false)
398
+ def sort(by, reverse: false, nulls_last: false, maintain_order: false)
383
399
  if by.is_a?(String)
384
- _from_rbldf(_ldf.sort(by, reverse, nulls_last))
400
+ return _from_rbldf(_ldf.sort(by, reverse, nulls_last, maintain_order))
385
401
  end
386
402
  if Utils.bool?(reverse)
387
403
  reverse = [reverse]
388
404
  end
389
405
 
390
406
  by = Utils.selection_to_rbexpr_list(by)
391
- _from_rbldf(_ldf.sort_by_exprs(by, reverse, nulls_last))
407
+ _from_rbldf(_ldf.sort_by_exprs(by, reverse, nulls_last, maintain_order))
392
408
  end
393
409
 
394
410
  # def profile
@@ -921,6 +937,12 @@ module Polars
921
937
  # Define whether the temporal window interval is closed or not.
922
938
  # @param by [Object]
923
939
  # Also group by this column/these columns.
940
+ # @param check_sorted [Boolean]
941
+ # When the `by` argument is given, polars can not check sortedness
942
+ # by the metadata and has to do a full scan on the index column to
943
+ # verify data is sorted. This is expensive. If you are sure the
944
+ # data within the by groups is sorted, you can set this to `false`.
945
+ # Doing so incorrectly will lead to incorrect output
924
946
  #
925
947
  # @return [LazyFrame]
926
948
  #
@@ -933,8 +955,8 @@ module Polars
933
955
  # "2020-01-03 19:45:32",
934
956
  # "2020-01-08 23:16:43"
935
957
  # ]
936
- # df = Polars::DataFrame.new({"dt" => dates, "a" => [3, 7, 5, 9, 2, 1]}).with_column(
937
- # Polars.col("dt").str.strptime(Polars::Datetime)
958
+ # df = Polars::LazyFrame.new({"dt" => dates, "a" => [3, 7, 5, 9, 2, 1]}).with_column(
959
+ # Polars.col("dt").str.strptime(Polars::Datetime).set_sorted
938
960
  # )
939
961
  # df.groupby_rolling(index_column: "dt", period: "2d").agg(
940
962
  # [
@@ -942,7 +964,7 @@ module Polars
942
964
  # Polars.min("a").alias("min_a"),
943
965
  # Polars.max("a").alias("max_a")
944
966
  # ]
945
- # )
967
+ # ).collect
946
968
  # # =>
947
969
  # # shape: (6, 4)
948
970
  # # ┌─────────────────────┬───────┬───────┬───────┐
@@ -962,7 +984,8 @@ module Polars
962
984
  period:,
963
985
  offset: nil,
964
986
  closed: "right",
965
- by: nil
987
+ by: nil,
988
+ check_sorted: true
966
989
  )
967
990
  index_column = Utils.expr_to_lit_or_expr(index_column, str_to_lit: false)
968
991
  if offset.nil?
@@ -974,7 +997,7 @@ module Polars
974
997
  offset = Utils._timedelta_to_pl_duration(offset)
975
998
 
976
999
  lgb = _ldf.groupby_rolling(
977
- index_column._rbexpr, period, offset, closed, rbexprs_by
1000
+ index_column._rbexpr, period, offset, closed, rbexprs_by, check_sorted
978
1001
  )
979
1002
  LazyGroupBy.new(lgb, self.class)
980
1003
  end
@@ -1112,21 +1135,21 @@ module Polars
1112
1135
  # df.groupby_dynamic("time", every: "1h", closed: "left").agg(
1113
1136
  # [
1114
1137
  # Polars.col("time").count.alias("time_count"),
1115
- # Polars.col("time").list.alias("time_agg_list")
1138
+ # Polars.col("time").alias("time_agg_list")
1116
1139
  # ]
1117
1140
  # )
1118
1141
  # # =>
1119
1142
  # # shape: (4, 3)
1120
- # # ┌─────────────────────┬────────────┬─────────────────────────────────────┐
1121
- # # │ time ┆ time_count ┆ time_agg_list
1122
- # # │ --- ┆ --- ┆ ---
1123
- # # │ datetime[μs] ┆ u32 ┆ list[datetime[μs]]
1124
- # # ╞═════════════════════╪════════════╪═════════════════════════════════════╡
1125
- # # │ 2021-12-16 00:00:00 ┆ 2 ┆ [2021-12-16 00:00:00, 2021-12-16...
1126
- # # │ 2021-12-16 01:00:00 ┆ 2 ┆ [2021-12-16 01:00:00, 2021-12-16...
1127
- # # │ 2021-12-16 02:00:00 ┆ 2 ┆ [2021-12-16 02:00:00, 2021-12-16...
1128
- # # │ 2021-12-16 03:00:00 ┆ 1 ┆ [2021-12-16 03:00:00]
1129
- # # └─────────────────────┴────────────┴─────────────────────────────────────┘
1143
+ # # ┌─────────────────────┬────────────┬───────────────────────────────────┐
1144
+ # # │ time ┆ time_count ┆ time_agg_list
1145
+ # # │ --- ┆ --- ┆ ---
1146
+ # # │ datetime[μs] ┆ u32 ┆ list[datetime[μs]]
1147
+ # # ╞═════════════════════╪════════════╪═══════════════════════════════════╡
1148
+ # # │ 2021-12-16 00:00:00 ┆ 2 ┆ [2021-12-16 00:00:00, 2021-12-16
1149
+ # # │ 2021-12-16 01:00:00 ┆ 2 ┆ [2021-12-16 01:00:00, 2021-12-16
1150
+ # # │ 2021-12-16 02:00:00 ┆ 2 ┆ [2021-12-16 02:00:00, 2021-12-16
1151
+ # # │ 2021-12-16 03:00:00 ┆ 1 ┆ [2021-12-16 03:00:00]
1152
+ # # └─────────────────────┴────────────┴───────────────────────────────────┘
1130
1153
  #
1131
1154
  # @example When closed="both" the time values at the window boundaries belong to 2 groups.
1132
1155
  # df.groupby_dynamic("time", every: "1h", closed: "both").agg(
@@ -1193,7 +1216,7 @@ module Polars
1193
1216
  # period: "3i",
1194
1217
  # include_boundaries: true,
1195
1218
  # closed: "right"
1196
- # ).agg(Polars.col("A").list.alias("A_agg_list"))
1219
+ # ).agg(Polars.col("A").alias("A_agg_list"))
1197
1220
  # # =>
1198
1221
  # # shape: (3, 4)
1199
1222
  # # ┌─────────────────┬─────────────────┬─────┬─────────────────┐
@@ -1216,12 +1239,9 @@ module Polars
1216
1239
  by: nil,
1217
1240
  start_by: "window"
1218
1241
  )
1242
+ index_column = Utils.expr_to_lit_or_expr(index_column, str_to_lit: false)
1219
1243
  if offset.nil?
1220
- if period.nil?
1221
- offset = "-#{every}"
1222
- else
1223
- offset = "0ns"
1224
- end
1244
+ offset = period.nil? ? "-#{every}" : "0ns"
1225
1245
  end
1226
1246
 
1227
1247
  if period.nil?
@@ -1234,7 +1254,7 @@ module Polars
1234
1254
 
1235
1255
  rbexprs_by = by.nil? ? [] : Utils.selection_to_rbexpr_list(by)
1236
1256
  lgb = _ldf.groupby_dynamic(
1237
- index_column,
1257
+ index_column._rbexpr,
1238
1258
  every,
1239
1259
  period,
1240
1260
  offset,
@@ -1351,7 +1371,7 @@ module Polars
1351
1371
  if by.is_a?(String)
1352
1372
  by_left_ = [by]
1353
1373
  by_right_ = [by]
1354
- elsif by.is_a?(Array)
1374
+ elsif by.is_a?(::Array)
1355
1375
  by_left_ = by
1356
1376
  by_right_ = by
1357
1377
  end
@@ -1619,7 +1639,7 @@ module Polars
1619
1639
  # # │ null │
1620
1640
  # # └──────┘
1621
1641
  def with_context(other)
1622
- if !other.is_a?(Array)
1642
+ if !other.is_a?(::Array)
1623
1643
  other = [other]
1624
1644
  end
1625
1645
 
@@ -2228,7 +2248,7 @@ module Polars
2228
2248
  #
2229
2249
  # @return [LazyFrame]
2230
2250
  def unique(maintain_order: true, subset: nil, keep: "first")
2231
- if !subset.nil? && !subset.is_a?(Array)
2251
+ if !subset.nil? && !subset.is_a?(::Array)
2232
2252
  subset = [subset]
2233
2253
  end
2234
2254
  _from_rbldf(_ldf.unique(maintain_order, subset, keep))
@@ -2261,7 +2281,7 @@ module Polars
2261
2281
  # # │ 3 ┆ 8 ┆ c │
2262
2282
  # # └─────┴─────┴─────┘
2263
2283
  def drop_nulls(subset: nil)
2264
- if !subset.nil? && !subset.is_a?(Array)
2284
+ if !subset.nil? && !subset.is_a?(::Array)
2265
2285
  subset = [subset]
2266
2286
  end
2267
2287
  _from_rbldf(_ldf.drop_nulls(subset))
@@ -2423,6 +2443,38 @@ module Polars
2423
2443
  _from_rbldf(_ldf.unnest(names))
2424
2444
  end
2425
2445
 
2446
+ # TODO
2447
+ # def merge_sorted
2448
+ # end
2449
+
2450
+ # Indicate that one or multiple columns are sorted.
2451
+ #
2452
+ # @param column [Object]
2453
+ # Columns that are sorted
2454
+ # @param more_columns [Object]
2455
+ # Additional columns that are sorted, specified as positional arguments.
2456
+ # @param descending [Boolean]
2457
+ # Whether the columns are sorted in descending order.
2458
+ #
2459
+ # @return [LazyFrame]
2460
+ def set_sorted(
2461
+ column,
2462
+ *more_columns,
2463
+ descending: false
2464
+ )
2465
+ columns = Utils.selection_to_rbexpr_list(column)
2466
+ if more_columns.any?
2467
+ columns.concat(Utils.selection_to_rbexpr_list(more_columns))
2468
+ end
2469
+ with_columns(
2470
+ columns.map { |e| Utils.wrap_expr(e).set_sorted(descending: descending) }
2471
+ )
2472
+ end
2473
+
2474
+ # TODO
2475
+ # def update
2476
+ # end
2477
+
2426
2478
  private
2427
2479
 
2428
2480
  def initialize_copy(other)