polars-df 0.20.0-x64-mingw-ucrt → 0.21.1-x64-mingw-ucrt

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/Cargo.lock +192 -186
  4. data/LICENSE-THIRD-PARTY.txt +2153 -2532
  5. data/LICENSE.txt +1 -1
  6. data/lib/polars/3.2/polars.so +0 -0
  7. data/lib/polars/3.3/polars.so +0 -0
  8. data/lib/polars/3.4/polars.so +0 -0
  9. data/lib/polars/array_expr.rb +382 -3
  10. data/lib/polars/array_name_space.rb +281 -0
  11. data/lib/polars/binary_expr.rb +67 -0
  12. data/lib/polars/binary_name_space.rb +43 -0
  13. data/lib/polars/cat_expr.rb +224 -0
  14. data/lib/polars/cat_name_space.rb +130 -32
  15. data/lib/polars/catalog/unity/catalog_info.rb +20 -0
  16. data/lib/polars/catalog/unity/column_info.rb +31 -0
  17. data/lib/polars/catalog/unity/namespace_info.rb +21 -0
  18. data/lib/polars/catalog/unity/table_info.rb +50 -0
  19. data/lib/polars/catalog.rb +448 -0
  20. data/lib/polars/config.rb +2 -2
  21. data/lib/polars/convert.rb +12 -2
  22. data/lib/polars/data_frame.rb +834 -48
  23. data/lib/polars/data_type_expr.rb +52 -0
  24. data/lib/polars/data_types.rb +61 -5
  25. data/lib/polars/date_time_expr.rb +251 -0
  26. data/lib/polars/date_time_name_space.rb +299 -0
  27. data/lib/polars/exceptions.rb +7 -2
  28. data/lib/polars/expr.rb +1247 -211
  29. data/lib/polars/functions/col.rb +6 -5
  30. data/lib/polars/functions/datatype.rb +21 -0
  31. data/lib/polars/functions/lazy.rb +127 -15
  32. data/lib/polars/functions/repeat.rb +4 -0
  33. data/lib/polars/io/csv.rb +19 -1
  34. data/lib/polars/io/json.rb +16 -0
  35. data/lib/polars/io/ndjson.rb +13 -0
  36. data/lib/polars/io/parquet.rb +70 -66
  37. data/lib/polars/io/scan_options.rb +47 -0
  38. data/lib/polars/lazy_frame.rb +1099 -95
  39. data/lib/polars/list_expr.rb +400 -11
  40. data/lib/polars/list_name_space.rb +321 -5
  41. data/lib/polars/meta_expr.rb +71 -22
  42. data/lib/polars/name_expr.rb +36 -0
  43. data/lib/polars/scan_cast_options.rb +64 -0
  44. data/lib/polars/schema.rb +84 -3
  45. data/lib/polars/selector.rb +210 -0
  46. data/lib/polars/selectors.rb +932 -203
  47. data/lib/polars/series.rb +1083 -63
  48. data/lib/polars/string_expr.rb +435 -9
  49. data/lib/polars/string_name_space.rb +729 -45
  50. data/lib/polars/struct_expr.rb +103 -0
  51. data/lib/polars/struct_name_space.rb +19 -1
  52. data/lib/polars/utils/parse.rb +40 -0
  53. data/lib/polars/utils/various.rb +18 -1
  54. data/lib/polars/utils.rb +9 -1
  55. data/lib/polars/version.rb +1 -1
  56. data/lib/polars.rb +10 -0
  57. metadata +12 -2
@@ -80,10 +80,10 @@ module Polars
80
80
  # # │ 2 │
81
81
  # # │ 1 │
82
82
  # # └─────┘
83
- def lengths
83
+ def len
84
84
  Utils.wrap_expr(_rbexpr.list_len)
85
85
  end
86
- alias_method :len, :lengths
86
+ alias_method :lengths, :len
87
87
 
88
88
  # Drop all null values in the list.
89
89
  #
@@ -136,7 +136,7 @@ module Polars
136
136
  # # │ --- ┆ --- ┆ --- │
137
137
  # # │ list[i64] ┆ i64 ┆ list[i64] │
138
138
  # # ╞═══════════╪═════╪═══════════╡
139
- # # │ [1, 2, 3] ┆ 2 ┆ [2, 1] │
139
+ # # │ [1, 2, 3] ┆ 2 ┆ [2, 3] │
140
140
  # # │ [4, 5] ┆ 1 ┆ [5] │
141
141
  # # └───────────┴─────┴───────────┘
142
142
  def sample(n: nil, fraction: nil, with_replacement: false, shuffle: false, seed: nil)
@@ -243,6 +243,79 @@ module Polars
243
243
  Utils.wrap_expr(_rbexpr.list_mean)
244
244
  end
245
245
 
246
+ # Compute the median value of the lists in the array.
247
+ #
248
+ # @return [Expr]
249
+ #
250
+ # @example
251
+ # df = Polars::DataFrame.new({"values" => [[-1, 0, 1], [1, 10]]})
252
+ # df.with_columns(Polars.col("values").list.median.alias("median"))
253
+ # # =>
254
+ # # shape: (2, 2)
255
+ # # ┌────────────┬────────┐
256
+ # # │ values ┆ median │
257
+ # # │ --- ┆ --- │
258
+ # # │ list[i64] ┆ f64 │
259
+ # # ╞════════════╪════════╡
260
+ # # │ [-1, 0, 1] ┆ 0.0 │
261
+ # # │ [1, 10] ┆ 5.5 │
262
+ # # └────────────┴────────┘
263
+ def median
264
+ Utils.wrap_expr(_rbexpr.list_median)
265
+ end
266
+
267
+ # Compute the std value of the lists in the array.
268
+ #
269
+ # @param ddof [Integer]
270
+ # “Delta Degrees of Freedom”: the divisor used in the calculation is N - ddof,
271
+ # where N represents the number of elements.
272
+ # By default ddof is 1.
273
+ #
274
+ # @return [Expr]
275
+ #
276
+ # @example
277
+ # df = Polars::DataFrame.new({"values" => [[-1, 0, 1], [1, 10]]})
278
+ # df.with_columns(Polars.col("values").list.std.alias("std"))
279
+ # # =>
280
+ # # shape: (2, 2)
281
+ # # ┌────────────┬──────────┐
282
+ # # │ values ┆ std │
283
+ # # │ --- ┆ --- │
284
+ # # │ list[i64] ┆ f64 │
285
+ # # ╞════════════╪══════════╡
286
+ # # │ [-1, 0, 1] ┆ 1.0 │
287
+ # # │ [1, 10] ┆ 6.363961 │
288
+ # # └────────────┴──────────┘
289
+ def std(ddof: 1)
290
+ Utils.wrap_expr(_rbexpr.list_std(ddof))
291
+ end
292
+
293
+ # Compute the var value of the lists in the array.
294
+ #
295
+ # @param ddof [Integer]
296
+ # “Delta Degrees of Freedom”: the divisor used in the calculation is N - ddof,
297
+ # where N represents the number of elements.
298
+ # By default ddof is 1.
299
+ #
300
+ # @return [Expr]
301
+ #
302
+ # @example
303
+ # df = Polars::DataFrame.new({"values" => [[-1, 0, 1], [1, 10]]})
304
+ # df.with_columns(Polars.col("values").list.var.alias("var"))
305
+ # # =>
306
+ # # shape: (2, 2)
307
+ # # ┌────────────┬──────┐
308
+ # # │ values ┆ var │
309
+ # # │ --- ┆ --- │
310
+ # # │ list[i64] ┆ f64 │
311
+ # # ╞════════════╪══════╡
312
+ # # │ [-1, 0, 1] ┆ 1.0 │
313
+ # # │ [1, 10] ┆ 40.5 │
314
+ # # └────────────┴──────┘
315
+ def var(ddof: 1)
316
+ Utils.wrap_expr(_rbexpr.list_var(ddof))
317
+ end
318
+
246
319
  # Sort the arrays in the list.
247
320
  #
248
321
  # @param reverse [Boolean]
@@ -322,6 +395,31 @@ module Polars
322
395
  Utils.wrap_expr(_rbexpr.list_unique(maintain_order))
323
396
  end
324
397
 
398
+ # Count the number of unique values in every sub-lists.
399
+ #
400
+ # @return [Expr]
401
+ #
402
+ # @example
403
+ # df = Polars::DataFrame.new(
404
+ # {
405
+ # "a" => [[1, 1, 2], [2, 3, 4]]
406
+ # }
407
+ # )
408
+ # df.with_columns(n_unique: Polars.col("a").list.n_unique)
409
+ # # =>
410
+ # # shape: (2, 2)
411
+ # # ┌───────────┬──────────┐
412
+ # # │ a ┆ n_unique │
413
+ # # │ --- ┆ --- │
414
+ # # │ list[i64] ┆ u32 │
415
+ # # ╞═══════════╪══════════╡
416
+ # # │ [1, 1, 2] ┆ 2 │
417
+ # # │ [2, 3, 4] ┆ 3 │
418
+ # # └───────────┴──────────┘
419
+ def n_unique
420
+ Utils.wrap_expr(_rbexpr.list_n_unique)
421
+ end
422
+
325
423
  # Concat the arrays in a Series dtype List in linear time.
326
424
  #
327
425
  # @param other [Object]
@@ -366,7 +464,7 @@ module Polars
366
464
  #
367
465
  # So index `0` would return the first item of every sublist
368
466
  # and index `-1` would return the last item of every sublist
369
- # if an index is out of bounds, it will return a `None`.
467
+ # if an index is out of bounds, it will return a `nil`.
370
468
  #
371
469
  # @param index [Integer]
372
470
  # Index to return per sublist
@@ -438,6 +536,48 @@ module Polars
438
536
  end
439
537
  alias_method :take, :gather
440
538
 
539
+ # Take every n-th value start from offset in sublists.
540
+ #
541
+ # @param n [Integer]
542
+ # Gather every n-th element.
543
+ # @param offset [Integer]
544
+ # Starting index.
545
+ #
546
+ # @return [Expr]
547
+ #
548
+ # @example
549
+ # df = Polars::DataFrame.new(
550
+ # {
551
+ # "a" => [[1, 2, 3, 4, 5], [6, 7, 8], [9, 10, 11, 12]],
552
+ # "n" => [2, 1, 3],
553
+ # "offset" => [0, 1, 0]
554
+ # }
555
+ # )
556
+ # df.with_columns(
557
+ # gather_every: Polars.col("a").list.gather_every(
558
+ # Polars.col("n"), Polars.col("offset")
559
+ # )
560
+ # )
561
+ # # =>
562
+ # # shape: (3, 4)
563
+ # # ┌───────────────┬─────┬────────┬──────────────┐
564
+ # # │ a ┆ n ┆ offset ┆ gather_every │
565
+ # # │ --- ┆ --- ┆ --- ┆ --- │
566
+ # # │ list[i64] ┆ i64 ┆ i64 ┆ list[i64] │
567
+ # # ╞═══════════════╪═════╪════════╪══════════════╡
568
+ # # │ [1, 2, … 5] ┆ 2 ┆ 0 ┆ [1, 3, 5] │
569
+ # # │ [6, 7, 8] ┆ 1 ┆ 1 ┆ [7, 8] │
570
+ # # │ [9, 10, … 12] ┆ 3 ┆ 0 ┆ [9, 12] │
571
+ # # └───────────────┴─────┴────────┴──────────────┘
572
+ def gather_every(
573
+ n,
574
+ offset = 0
575
+ )
576
+ n = Utils.parse_into_expression(n)
577
+ offset = Utils.parse_into_expression(offset)
578
+ Utils.wrap_expr(_rbexpr.list_gather_every(n, offset))
579
+ end
580
+
441
581
  # Get the first value of the sublists.
442
582
  #
443
583
  # @return [Expr]
@@ -702,7 +842,32 @@ module Polars
702
842
  Utils.wrap_expr(_rbexpr.list_tail(n))
703
843
  end
704
844
 
705
- # Count how often the value produced by ``element`` occurs.
845
+ # Returns a column with a separate row for every list element.
846
+ #
847
+ # @return [Expr]
848
+ #
849
+ # @example
850
+ # df = Polars::DataFrame.new({"a" => [[1, 2, 3], [4, 5, 6]]})
851
+ # df.select(Polars.col("a").list.explode)
852
+ # # =>
853
+ # # shape: (6, 1)
854
+ # # ┌─────┐
855
+ # # │ a │
856
+ # # │ --- │
857
+ # # │ i64 │
858
+ # # ╞═════╡
859
+ # # │ 1 │
860
+ # # │ 2 │
861
+ # # │ 3 │
862
+ # # │ 4 │
863
+ # # │ 5 │
864
+ # # │ 6 │
865
+ # # └─────┘
866
+ def explode
867
+ Utils.wrap_expr(_rbexpr.explode)
868
+ end
869
+
870
+ # Count how often the value produced by `element` occurs.
706
871
  #
707
872
  # @param element [Expr]
708
873
  # An expression that produces a single value
@@ -730,13 +895,52 @@ module Polars
730
895
  end
731
896
  alias_method :count_match, :count_matches
732
897
 
898
+ # Convert a List column into an Array column with the same inner data type.
899
+ #
900
+ # @param width [Integer]
901
+ # Width of the resulting Array column.
902
+ #
903
+ # @return [Expr]
904
+ #
905
+ # @example
906
+ # df = Polars::DataFrame.new(
907
+ # {"a" => [[1, 2], [3, 4]]},
908
+ # schema: {"a" => Polars::List.new(Polars::Int8)}
909
+ # )
910
+ # df.with_columns(array: Polars.col("a").list.to_array(2))
911
+ # # =>
912
+ # # shape: (2, 2)
913
+ # # ┌──────────┬──────────────┐
914
+ # # │ a ┆ array │
915
+ # # │ --- ┆ --- │
916
+ # # │ list[i8] ┆ array[i8, 2] │
917
+ # # ╞══════════╪══════════════╡
918
+ # # │ [1, 2] ┆ [1, 2] │
919
+ # # │ [3, 4] ┆ [3, 4] │
920
+ # # └──────────┴──────────────┘
921
+ def to_array(width)
922
+ Utils.wrap_expr(_rbexpr.list_to_array(width))
923
+ end
924
+
733
925
  # Convert the series of type `List` to a series of type `Struct`.
734
926
  #
735
927
  # @param n_field_strategy ["first_non_null", "max_width"]
736
928
  # Strategy to determine the number of fields of the struct.
737
- # @param name_generator [Object]
738
- # A custom function that can be used to generate the field names.
739
- # Default field names are `field_0, field_1 .. field_n`
929
+ # @param fields pArray
930
+ # If the name and number of the desired fields is known in advance
931
+ # a list of field names can be given, which will be assigned by index.
932
+ # Otherwise, to dynamically assign field names, a custom function can be
933
+ # used; if neither are set, fields will be `field_0, field_1 .. field_n`.
934
+ # @param upper_bound [Object]
935
+ # A polars `LazyFrame` needs to know the schema at all times, so the
936
+ # caller must provide an upper bound of the number of struct fields that
937
+ # will be created; if set incorrectly, subsequent operations may fail.
938
+ # (For example, an `all.sum` expression will look in the current
939
+ # schema to determine which columns to select).
940
+ #
941
+ # When operating on a `DataFrame`, the schema does not need to be
942
+ # tracked or pre-determined, as the result will be eagerly evaluated,
943
+ # so you can leave this parameter unset.
740
944
  #
741
945
  # @return [Expr]
742
946
  #
@@ -753,9 +957,8 @@ module Polars
753
957
  # # │ {1,2,3} │
754
958
  # # │ {1,2,null} │
755
959
  # # └────────────┘
756
- def to_struct(n_field_strategy: "first_non_null", name_generator: nil, upper_bound: nil)
757
- raise Todo if name_generator
758
- Utils.wrap_expr(_rbexpr.list_to_struct(n_field_strategy, name_generator, nil))
960
+ def to_struct(n_field_strategy: "first_non_null", fields: nil, upper_bound: nil)
961
+ Utils.wrap_expr(_rbexpr.list_to_struct(n_field_strategy, fields, nil))
759
962
  end
760
963
 
761
964
  # Run any polars expression against the lists' elements.
@@ -785,5 +988,191 @@ module Polars
785
988
  def eval(expr)
786
989
  Utils.wrap_expr(_rbexpr.list_eval(expr._rbexpr))
787
990
  end
991
+
992
+ # Filter elements in each list by a boolean expression.
993
+ #
994
+ # @param predicate [Object]
995
+ # A boolean expression that is evaluated per list element.
996
+ # You can refer to the current element with `Polars.element`.
997
+ #
998
+ # @return [Expr]
999
+ #
1000
+ # @example
1001
+ # df = Polars::DataFrame.new({"a" => [1, 8, 3], "b" => [4, 5, 2]})
1002
+ # df.with_columns(
1003
+ # evens: Polars.concat_list("a", "b").list.filter(Polars.element % 2 == 0)
1004
+ # )
1005
+ # # =>
1006
+ # # shape: (3, 3)
1007
+ # # ┌─────┬─────┬───────────┐
1008
+ # # │ a ┆ b ┆ evens │
1009
+ # # │ --- ┆ --- ┆ --- │
1010
+ # # │ i64 ┆ i64 ┆ list[i64] │
1011
+ # # ╞═════╪═════╪═══════════╡
1012
+ # # │ 1 ┆ 4 ┆ [4] │
1013
+ # # │ 8 ┆ 5 ┆ [8] │
1014
+ # # │ 3 ┆ 2 ┆ [2] │
1015
+ # # └─────┴─────┴───────────┘
1016
+ def filter(predicate)
1017
+ Utils.wrap_expr(_rbexpr.list_filter(predicate._rbexpr))
1018
+ end
1019
+
1020
+ # Compute the SET UNION between the elements in this list and the elements of `other`.
1021
+ #
1022
+ # @param other [Object]
1023
+ # Right hand side of the set operation.
1024
+ #
1025
+ # @return [Expr]
1026
+ #
1027
+ # @example
1028
+ # df = Polars::DataFrame.new(
1029
+ # {
1030
+ # "a" => [[1, 2, 3], [], [nil, 3], [5, 6, 7]],
1031
+ # "b" => [[2, 3, 4], [3], [3, 4, nil], [6, 8]]
1032
+ # }
1033
+ # )
1034
+ # df.with_columns(
1035
+ # union: Polars.col("a").list.set_union("b")
1036
+ # )
1037
+ # # =>
1038
+ # # shape: (4, 3)
1039
+ # # ┌───────────┬──────────────┬──────────────┐
1040
+ # # │ a ┆ b ┆ union │
1041
+ # # │ --- ┆ --- ┆ --- │
1042
+ # # │ list[i64] ┆ list[i64] ┆ list[i64] │
1043
+ # # ╞═══════════╪══════════════╪══════════════╡
1044
+ # # │ [1, 2, 3] ┆ [2, 3, 4] ┆ [1, 2, … 4] │
1045
+ # # │ [] ┆ [3] ┆ [3] │
1046
+ # # │ [null, 3] ┆ [3, 4, null] ┆ [null, 3, 4] │
1047
+ # # │ [5, 6, 7] ┆ [6, 8] ┆ [5, 6, … 8] │
1048
+ # # └───────────┴──────────────┴──────────────┘
1049
+ def set_union(other)
1050
+ if other.respond_to?(:each)
1051
+ if !other.is_a?(::Array) && !other.is_a?(Series) && !other.is_a?(DataFrame)
1052
+ other = other.to_a
1053
+ end
1054
+ other = F.lit(other)._rbexpr
1055
+ else
1056
+ other = Utils.parse_into_expression(other)
1057
+ end
1058
+ Utils.wrap_expr(_rbexpr.list_set_operation(other, "union"))
1059
+ end
1060
+
1061
+ # Compute the SET DIFFERENCE between the elements in this list and the elements of `other`.
1062
+ #
1063
+ # @param other [Object]
1064
+ # Right hand side of the set operation.
1065
+ #
1066
+ # @return [Expr]
1067
+ #
1068
+ # @example
1069
+ # df = Polars::DataFrame.new(
1070
+ # {
1071
+ # "a" => [[1, 2, 3], [], [nil, 3], [5, 6, 7]],
1072
+ # "b" => [[2, 3, 4], [3], [3, 4, nil], [6, 8]]
1073
+ # }
1074
+ # )
1075
+ # df.with_columns(difference: Polars.col("a").list.set_difference("b"))
1076
+ # # =>
1077
+ # # shape: (4, 3)
1078
+ # # ┌───────────┬──────────────┬────────────┐
1079
+ # # │ a ┆ b ┆ difference │
1080
+ # # │ --- ┆ --- ┆ --- │
1081
+ # # │ list[i64] ┆ list[i64] ┆ list[i64] │
1082
+ # # ╞═══════════╪══════════════╪════════════╡
1083
+ # # │ [1, 2, 3] ┆ [2, 3, 4] ┆ [1] │
1084
+ # # │ [] ┆ [3] ┆ [] │
1085
+ # # │ [null, 3] ┆ [3, 4, null] ┆ [] │
1086
+ # # │ [5, 6, 7] ┆ [6, 8] ┆ [5, 7] │
1087
+ # # └───────────┴──────────────┴────────────┘
1088
+ def set_difference(other)
1089
+ if other.respond_to?(:each)
1090
+ if !other.is_a?(::Array) && !other.is_a?(Series) && !other.is_a?(DataFrame)
1091
+ other = other.to_a
1092
+ end
1093
+ other = F.lit(other)._rbexpr
1094
+ else
1095
+ other = Utils.parse_into_expression(other)
1096
+ end
1097
+ Utils.wrap_expr(_rbexpr.list_set_operation(other, "difference"))
1098
+ end
1099
+
1100
+ # Compute the SET INTERSECTION between the elements in this list and the elements of `other`.
1101
+ #
1102
+ # @param other [Object]
1103
+ # Right hand side of the set operation.
1104
+ #
1105
+ # @return [Expr]
1106
+ #
1107
+ # @example
1108
+ # df = Polars::DataFrame.new(
1109
+ # {
1110
+ # "a" => [[1, 2, 3], [], [nil, 3], [5, 6, 7]],
1111
+ # "b" => [[2, 3, 4], [3], [3, 4, nil], [6, 8]]
1112
+ # }
1113
+ # )
1114
+ # df.with_columns(intersection: Polars.col("a").list.set_intersection("b"))
1115
+ # # =>
1116
+ # # shape: (4, 3)
1117
+ # # ┌───────────┬──────────────┬──────────────┐
1118
+ # # │ a ┆ b ┆ intersection │
1119
+ # # │ --- ┆ --- ┆ --- │
1120
+ # # │ list[i64] ┆ list[i64] ┆ list[i64] │
1121
+ # # ╞═══════════╪══════════════╪══════════════╡
1122
+ # # │ [1, 2, 3] ┆ [2, 3, 4] ┆ [2, 3] │
1123
+ # # │ [] ┆ [3] ┆ [] │
1124
+ # # │ [null, 3] ┆ [3, 4, null] ┆ [null, 3] │
1125
+ # # │ [5, 6, 7] ┆ [6, 8] ┆ [6] │
1126
+ # # └───────────┴──────────────┴──────────────┘
1127
+ def set_intersection(other)
1128
+ if other.respond_to?(:each)
1129
+ if !other.is_a?(::Array) && !other.is_a?(Series) && !other.is_a?(DataFrame)
1130
+ other = other.to_a
1131
+ end
1132
+ other = F.lit(other)._rbexpr
1133
+ else
1134
+ other = Utils.parse_into_expression(other)
1135
+ end
1136
+ Utils.wrap_expr(_rbexpr.list_set_operation(other, "intersection"))
1137
+ end
1138
+
1139
+ # Compute the SET SYMMETRIC DIFFERENCE between the elements in this list and the elements of `other`.
1140
+ #
1141
+ # @param other [Object]
1142
+ # Right hand side of the set operation.
1143
+ #
1144
+ # @return [Expr]
1145
+ #
1146
+ # @example
1147
+ # df = Polars::DataFrame.new(
1148
+ # {
1149
+ # "a" => [[1, 2, 3], [], [nil, 3], [5, 6, 7]],
1150
+ # "b" => [[2, 3, 4], [3], [3, 4, nil], [6, 8]]
1151
+ # }
1152
+ # )
1153
+ # df.with_columns(sdiff: Polars.col("b").list.set_symmetric_difference("a"))
1154
+ # # =>
1155
+ # # shape: (4, 3)
1156
+ # # ┌───────────┬──────────────┬───────────┐
1157
+ # # │ a ┆ b ┆ sdiff │
1158
+ # # │ --- ┆ --- ┆ --- │
1159
+ # # │ list[i64] ┆ list[i64] ┆ list[i64] │
1160
+ # # ╞═══════════╪══════════════╪═══════════╡
1161
+ # # │ [1, 2, 3] ┆ [2, 3, 4] ┆ [4, 1] │
1162
+ # # │ [] ┆ [3] ┆ [3] │
1163
+ # # │ [null, 3] ┆ [3, 4, null] ┆ [4] │
1164
+ # # │ [5, 6, 7] ┆ [6, 8] ┆ [8, 5, 7] │
1165
+ # # └───────────┴──────────────┴───────────┘
1166
+ def set_symmetric_difference(other)
1167
+ if other.respond_to?(:each)
1168
+ if !other.is_a?(::Array) && !other.is_a?(Series) && !other.is_a?(DataFrame)
1169
+ other = other.to_a
1170
+ end
1171
+ other = F.lit(other)._rbexpr
1172
+ else
1173
+ other = Utils.parse_into_expression(other)
1174
+ end
1175
+ Utils.wrap_expr(_rbexpr.list_set_operation(other, "symmetric_difference"))
1176
+ end
788
1177
  end
789
1178
  end