polars-df 0.15.0 → 0.26.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +274 -0
- data/Cargo.lock +1465 -867
- data/Cargo.toml +3 -0
- data/LICENSE.txt +2 -2
- data/README.md +87 -37
- data/ext/polars/Cargo.toml +47 -16
- data/ext/polars/src/c_api/allocator.rs +7 -0
- data/ext/polars/src/c_api/mod.rs +1 -0
- data/ext/polars/src/catalog/mod.rs +1 -0
- data/ext/polars/src/catalog/unity.rs +470 -0
- data/ext/polars/src/conversion/any_value.rs +99 -84
- data/ext/polars/src/conversion/categorical.rs +30 -0
- data/ext/polars/src/conversion/chunked_array.rs +71 -62
- data/ext/polars/src/conversion/datetime.rs +63 -0
- data/ext/polars/src/conversion/mod.rs +796 -312
- data/ext/polars/src/dataframe/construction.rs +6 -18
- data/ext/polars/src/dataframe/export.rs +30 -39
- data/ext/polars/src/dataframe/general.rs +294 -362
- data/ext/polars/src/dataframe/io.rs +33 -150
- data/ext/polars/src/dataframe/map.rs +175 -0
- data/ext/polars/src/dataframe/mod.rs +37 -5
- data/ext/polars/src/dataframe/serde.rs +23 -8
- data/ext/polars/src/error.rs +44 -7
- data/ext/polars/src/exceptions.rs +21 -8
- data/ext/polars/src/expr/array.rs +86 -22
- data/ext/polars/src/expr/binary.rs +50 -1
- data/ext/polars/src/expr/bitwise.rs +39 -0
- data/ext/polars/src/expr/categorical.rs +20 -0
- data/ext/polars/src/expr/datatype.rs +51 -0
- data/ext/polars/src/expr/datetime.rs +99 -41
- data/ext/polars/src/expr/extension.rs +12 -0
- data/ext/polars/src/expr/general.rs +252 -128
- data/ext/polars/src/expr/list.rs +56 -60
- data/ext/polars/src/expr/meta.rs +30 -35
- data/ext/polars/src/expr/mod.rs +28 -6
- data/ext/polars/src/expr/name.rs +29 -14
- data/ext/polars/src/expr/rolling.rs +111 -3
- data/ext/polars/src/expr/selector.rs +219 -0
- data/ext/polars/src/expr/serde.rs +28 -0
- data/ext/polars/src/expr/string.rs +118 -20
- data/ext/polars/src/expr/struct.rs +14 -1
- data/ext/polars/src/file.rs +194 -86
- data/ext/polars/src/functions/aggregation.rs +13 -12
- data/ext/polars/src/functions/business.rs +2 -3
- data/ext/polars/src/functions/eager.rs +3 -2
- data/ext/polars/src/functions/io.rs +90 -18
- data/ext/polars/src/functions/lazy.rs +267 -118
- data/ext/polars/src/functions/meta.rs +8 -7
- data/ext/polars/src/functions/misc.rs +1 -1
- data/ext/polars/src/functions/mod.rs +2 -1
- data/ext/polars/src/functions/range.rs +88 -31
- data/ext/polars/src/functions/strings.rs +6 -0
- data/ext/polars/src/functions/utils.rs +8 -0
- data/ext/polars/src/interop/arrow/mod.rs +52 -1
- data/ext/polars/src/interop/arrow/{to_ruby.rs → to_rb.rs} +37 -7
- data/ext/polars/src/interop/arrow/to_rust.rs +43 -0
- data/ext/polars/src/interop/numo/to_numo_df.rs +1 -1
- data/ext/polars/src/interop/numo/to_numo_series.rs +72 -50
- data/ext/polars/src/io/cloud_options.rs +107 -0
- data/ext/polars/src/io/mod.rs +4 -0
- data/ext/polars/src/io/scan_options.rs +113 -0
- data/ext/polars/src/io/sink_options.rs +46 -0
- data/ext/polars/src/io/sink_output.rs +21 -0
- data/ext/polars/src/lazyframe/exitable.rs +39 -0
- data/ext/polars/src/lazyframe/general.rs +846 -368
- data/ext/polars/src/lazyframe/mod.rs +58 -5
- data/ext/polars/src/lazyframe/optflags.rs +59 -0
- data/ext/polars/src/lazyframe/serde.rs +36 -4
- data/ext/polars/src/lazyframe/sink.rs +46 -0
- data/ext/polars/src/lazygroupby.rs +38 -9
- data/ext/polars/src/lib.rs +574 -165
- data/ext/polars/src/map/lazy.rs +44 -74
- data/ext/polars/src/map/mod.rs +18 -254
- data/ext/polars/src/map/series.rs +241 -1087
- data/ext/polars/src/on_startup.rs +192 -9
- data/ext/polars/src/prelude.rs +1 -0
- data/ext/polars/src/rb_modules.rs +10 -57
- data/ext/polars/src/ruby/exceptions.rs +26 -0
- data/ext/polars/src/ruby/gvl.rs +104 -0
- data/ext/polars/src/ruby/lazy.rs +46 -0
- data/ext/polars/src/ruby/mod.rs +11 -0
- data/ext/polars/src/ruby/numo.rs +52 -0
- data/ext/polars/src/ruby/plan_callback.rs +198 -0
- data/ext/polars/src/ruby/rb_modules.rs +16 -0
- data/ext/polars/src/ruby/ruby_convert_registry.rs +51 -0
- data/ext/polars/src/ruby/ruby_function.rs +11 -0
- data/ext/polars/src/ruby/ruby_udf.rs +164 -0
- data/ext/polars/src/ruby/thread.rs +65 -0
- data/ext/polars/src/ruby/utils.rs +39 -0
- data/ext/polars/src/series/aggregation.rs +116 -91
- data/ext/polars/src/series/arithmetic.rs +16 -22
- data/ext/polars/src/series/comparison.rs +101 -222
- data/ext/polars/src/series/construction.rs +80 -70
- data/ext/polars/src/series/export.rs +98 -56
- data/ext/polars/src/series/general.rs +323 -440
- data/ext/polars/src/series/import.rs +22 -5
- data/ext/polars/src/series/map.rs +103 -0
- data/ext/polars/src/series/mod.rs +57 -15
- data/ext/polars/src/series/scatter.rs +139 -82
- data/ext/polars/src/sql.rs +16 -9
- data/ext/polars/src/testing/frame.rs +31 -0
- data/ext/polars/src/testing/mod.rs +5 -0
- data/ext/polars/src/testing/series.rs +31 -0
- data/ext/polars/src/timeout.rs +105 -0
- data/ext/polars/src/utils.rs +105 -4
- data/lib/polars/array_expr.rb +500 -22
- data/lib/polars/array_name_space.rb +384 -10
- data/lib/polars/batched_csv_reader.rb +48 -66
- data/lib/polars/binary_expr.rb +217 -0
- data/lib/polars/binary_name_space.rb +155 -1
- data/lib/polars/cat_expr.rb +224 -0
- data/lib/polars/cat_name_space.rb +132 -32
- data/lib/polars/catalog/unity/catalog_info.rb +20 -0
- data/lib/polars/catalog/unity/column_info.rb +31 -0
- data/lib/polars/catalog/unity/namespace_info.rb +21 -0
- data/lib/polars/catalog/unity/table_info.rb +50 -0
- data/lib/polars/catalog.rb +448 -0
- data/lib/polars/collect_batches.rb +22 -0
- data/lib/polars/config.rb +3 -3
- data/lib/polars/convert.rb +201 -36
- data/lib/polars/data_frame.rb +2851 -1017
- data/lib/polars/data_frame_plot.rb +173 -0
- data/lib/polars/data_type_expr.rb +52 -0
- data/lib/polars/data_type_group.rb +6 -0
- data/lib/polars/data_types.rb +118 -18
- data/lib/polars/date_time_expr.rb +426 -84
- data/lib/polars/date_time_name_space.rb +384 -111
- data/lib/polars/dynamic_group_by.rb +102 -10
- data/lib/polars/exceptions.rb +50 -5
- data/lib/polars/expr.rb +2159 -915
- data/lib/polars/extension_expr.rb +39 -0
- data/lib/polars/extension_name_space.rb +39 -0
- data/lib/polars/functions/aggregation/horizontal.rb +11 -6
- data/lib/polars/functions/aggregation/vertical.rb +2 -3
- data/lib/polars/functions/as_datatype.rb +290 -8
- data/lib/polars/functions/business.rb +95 -0
- data/lib/polars/functions/col.rb +6 -5
- data/lib/polars/functions/datatype.rb +62 -0
- data/lib/polars/functions/eager.rb +426 -24
- data/lib/polars/functions/escape_regex.rb +21 -0
- data/lib/polars/functions/lazy.rb +813 -195
- data/lib/polars/functions/lit.rb +21 -10
- data/lib/polars/functions/range/int_range.rb +74 -2
- data/lib/polars/functions/range/linear_space.rb +195 -0
- data/lib/polars/functions/range/time_range.rb +1 -1
- data/lib/polars/functions/repeat.rb +7 -12
- data/lib/polars/functions/whenthen.rb +2 -2
- data/lib/polars/group_by.rb +188 -58
- data/lib/polars/iceberg_dataset.rb +108 -0
- data/lib/polars/in_process_query.rb +37 -0
- data/lib/polars/io/cloud.rb +18 -0
- data/lib/polars/io/csv.rb +336 -128
- data/lib/polars/io/database.rb +19 -4
- data/lib/polars/io/delta.rb +134 -0
- data/lib/polars/io/iceberg.rb +34 -0
- data/lib/polars/io/ipc.rb +63 -63
- data/lib/polars/io/json.rb +16 -0
- data/lib/polars/io/lines.rb +172 -0
- data/lib/polars/io/ndjson.rb +176 -20
- data/lib/polars/io/parquet.rb +173 -95
- data/lib/polars/io/scan_options.rb +55 -0
- data/lib/polars/io/sink_options.rb +27 -0
- data/lib/polars/io/utils.rb +17 -0
- data/lib/polars/lazy_frame.rb +3017 -622
- data/lib/polars/lazy_group_by.rb +436 -2
- data/lib/polars/list_expr.rb +551 -59
- data/lib/polars/list_name_space.rb +465 -51
- data/lib/polars/meta_expr.rb +146 -24
- data/lib/polars/name_expr.rb +87 -2
- data/lib/polars/query_opt_flags.rb +264 -0
- data/lib/polars/rolling_group_by.rb +90 -5
- data/lib/polars/scan_cast_options.rb +86 -0
- data/lib/polars/schema.rb +128 -0
- data/lib/polars/selector.rb +245 -0
- data/lib/polars/selectors.rb +1048 -201
- data/lib/polars/series.rb +2522 -774
- data/lib/polars/series_plot.rb +72 -0
- data/lib/polars/slice.rb +1 -1
- data/lib/polars/sql_context.rb +13 -6
- data/lib/polars/string_cache.rb +19 -72
- data/lib/polars/string_expr.rb +561 -107
- data/lib/polars/string_name_space.rb +781 -109
- data/lib/polars/struct_expr.rb +139 -18
- data/lib/polars/struct_name_space.rb +19 -1
- data/lib/polars/testing.rb +24 -273
- data/lib/polars/utils/constants.rb +2 -0
- data/lib/polars/utils/construction/data_frame.rb +410 -0
- data/lib/polars/utils/construction/series.rb +350 -0
- data/lib/polars/utils/construction/utils.rb +9 -0
- data/lib/polars/utils/convert.rb +18 -8
- data/lib/polars/utils/deprecation.rb +11 -0
- data/lib/polars/utils/parse.rb +62 -9
- data/lib/polars/utils/reduce_balanced.rb +43 -0
- data/lib/polars/utils/serde.rb +22 -0
- data/lib/polars/utils/unstable.rb +19 -0
- data/lib/polars/utils/various.rb +86 -1
- data/lib/polars/utils.rb +63 -48
- data/lib/polars/version.rb +1 -1
- data/lib/polars.rb +85 -2
- metadata +80 -28
- data/ext/polars/src/allocator.rs +0 -13
- data/ext/polars/src/batched_csv.rs +0 -138
- data/ext/polars/src/functions/string_cache.rs +0 -25
- data/ext/polars/src/map/dataframe.rs +0 -338
- data/lib/polars/plot.rb +0 -109
data/lib/polars/list_expr.rb
CHANGED
|
@@ -11,6 +11,13 @@ module Polars
|
|
|
11
11
|
|
|
12
12
|
# Evaluate whether all boolean values in a list are true.
|
|
13
13
|
#
|
|
14
|
+
# @param ignore_nulls [Boolean]
|
|
15
|
+
# * If set to `true` (default), null values are ignored. If there
|
|
16
|
+
# are no non-null values, the output is `true`.
|
|
17
|
+
# * If set to `false`, [Kleene logic](https://en.wikipedia.org/wiki/Three-valued_logic) is used to deal with nulls:
|
|
18
|
+
# if the column contains any null values and no `false` values,
|
|
19
|
+
# the output is null.
|
|
20
|
+
#
|
|
14
21
|
# @return [Expr]
|
|
15
22
|
#
|
|
16
23
|
# @example
|
|
@@ -32,12 +39,19 @@ module Polars
|
|
|
32
39
|
# # │ [] ┆ true │
|
|
33
40
|
# # │ null ┆ null │
|
|
34
41
|
# # └────────────────┴───────┘
|
|
35
|
-
def all
|
|
36
|
-
|
|
42
|
+
def all(ignore_nulls: true)
|
|
43
|
+
agg(F.element.all(ignore_nulls: ignore_nulls))
|
|
37
44
|
end
|
|
38
45
|
|
|
39
46
|
# Evaluate whether any boolean value in a list is true.
|
|
40
47
|
#
|
|
48
|
+
# @param ignore_nulls [Boolean]
|
|
49
|
+
# * If set to `true` (default), null values are ignored. If there
|
|
50
|
+
# are no non-null values, the output is `false`.
|
|
51
|
+
# * If set to `false`, [Kleene logic](https://en.wikipedia.org/wiki/Three-valued_logic) is used to deal with nulls:
|
|
52
|
+
# if the column contains any null values and no `true` values,
|
|
53
|
+
# the output is null.
|
|
54
|
+
#
|
|
41
55
|
# @return [Expr]
|
|
42
56
|
#
|
|
43
57
|
# @example
|
|
@@ -59,8 +73,8 @@ module Polars
|
|
|
59
73
|
# # │ [] ┆ false │
|
|
60
74
|
# # │ null ┆ null │
|
|
61
75
|
# # └────────────────┴───────┘
|
|
62
|
-
def any
|
|
63
|
-
|
|
76
|
+
def any(ignore_nulls: true)
|
|
77
|
+
agg(F.element.any(ignore_nulls: ignore_nulls))
|
|
64
78
|
end
|
|
65
79
|
|
|
66
80
|
# Get the length of the arrays as `:u32`.
|
|
@@ -69,7 +83,7 @@ module Polars
|
|
|
69
83
|
#
|
|
70
84
|
# @example
|
|
71
85
|
# df = Polars::DataFrame.new({"foo" => [1, 2], "bar" => [["a", "b"], ["c"]]})
|
|
72
|
-
# df.select(Polars.col("bar").list.
|
|
86
|
+
# df.select(Polars.col("bar").list.len)
|
|
73
87
|
# # =>
|
|
74
88
|
# # shape: (2, 1)
|
|
75
89
|
# # ┌─────┐
|
|
@@ -80,10 +94,9 @@ module Polars
|
|
|
80
94
|
# # │ 2 │
|
|
81
95
|
# # │ 1 │
|
|
82
96
|
# # └─────┘
|
|
83
|
-
def
|
|
97
|
+
def len
|
|
84
98
|
Utils.wrap_expr(_rbexpr.list_len)
|
|
85
99
|
end
|
|
86
|
-
alias_method :len, :lengths
|
|
87
100
|
|
|
88
101
|
# Drop all null values in the list.
|
|
89
102
|
#
|
|
@@ -136,7 +149,7 @@ module Polars
|
|
|
136
149
|
# # │ --- ┆ --- ┆ --- │
|
|
137
150
|
# # │ list[i64] ┆ i64 ┆ list[i64] │
|
|
138
151
|
# # ╞═══════════╪═════╪═══════════╡
|
|
139
|
-
# # │ [1, 2, 3] ┆ 2 ┆ [2,
|
|
152
|
+
# # │ [1, 2, 3] ┆ 2 ┆ [2, 3] │
|
|
140
153
|
# # │ [4, 5] ┆ 1 ┆ [5] │
|
|
141
154
|
# # └───────────┴─────┴───────────┘
|
|
142
155
|
def sample(n: nil, fraction: nil, with_replacement: false, shuffle: false, seed: nil)
|
|
@@ -243,8 +256,86 @@ module Polars
|
|
|
243
256
|
Utils.wrap_expr(_rbexpr.list_mean)
|
|
244
257
|
end
|
|
245
258
|
|
|
259
|
+
# Compute the median value of the lists in the array.
|
|
260
|
+
#
|
|
261
|
+
# @return [Expr]
|
|
262
|
+
#
|
|
263
|
+
# @example
|
|
264
|
+
# df = Polars::DataFrame.new({"values" => [[-1, 0, 1], [1, 10]]})
|
|
265
|
+
# df.with_columns(Polars.col("values").list.median.alias("median"))
|
|
266
|
+
# # =>
|
|
267
|
+
# # shape: (2, 2)
|
|
268
|
+
# # ┌────────────┬────────┐
|
|
269
|
+
# # │ values ┆ median │
|
|
270
|
+
# # │ --- ┆ --- │
|
|
271
|
+
# # │ list[i64] ┆ f64 │
|
|
272
|
+
# # ╞════════════╪════════╡
|
|
273
|
+
# # │ [-1, 0, 1] ┆ 0.0 │
|
|
274
|
+
# # │ [1, 10] ┆ 5.5 │
|
|
275
|
+
# # └────────────┴────────┘
|
|
276
|
+
def median
|
|
277
|
+
Utils.wrap_expr(_rbexpr.list_median)
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Compute the std value of the lists in the array.
|
|
281
|
+
#
|
|
282
|
+
# @param ddof [Integer]
|
|
283
|
+
# “Delta Degrees of Freedom”: the divisor used in the calculation is N - ddof,
|
|
284
|
+
# where N represents the number of elements.
|
|
285
|
+
# By default ddof is 1.
|
|
286
|
+
#
|
|
287
|
+
# @return [Expr]
|
|
288
|
+
#
|
|
289
|
+
# @example
|
|
290
|
+
# df = Polars::DataFrame.new({"values" => [[-1, 0, 1], [1, 10]]})
|
|
291
|
+
# df.with_columns(Polars.col("values").list.std.alias("std"))
|
|
292
|
+
# # =>
|
|
293
|
+
# # shape: (2, 2)
|
|
294
|
+
# # ┌────────────┬──────────┐
|
|
295
|
+
# # │ values ┆ std │
|
|
296
|
+
# # │ --- ┆ --- │
|
|
297
|
+
# # │ list[i64] ┆ f64 │
|
|
298
|
+
# # ╞════════════╪══════════╡
|
|
299
|
+
# # │ [-1, 0, 1] ┆ 1.0 │
|
|
300
|
+
# # │ [1, 10] ┆ 6.363961 │
|
|
301
|
+
# # └────────────┴──────────┘
|
|
302
|
+
def std(ddof: 1)
|
|
303
|
+
Utils.wrap_expr(_rbexpr.list_std(ddof))
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Compute the var value of the lists in the array.
|
|
307
|
+
#
|
|
308
|
+
# @param ddof [Integer]
|
|
309
|
+
# “Delta Degrees of Freedom”: the divisor used in the calculation is N - ddof,
|
|
310
|
+
# where N represents the number of elements.
|
|
311
|
+
# By default ddof is 1.
|
|
312
|
+
#
|
|
313
|
+
# @return [Expr]
|
|
314
|
+
#
|
|
315
|
+
# @example
|
|
316
|
+
# df = Polars::DataFrame.new({"values" => [[-1, 0, 1], [1, 10]]})
|
|
317
|
+
# df.with_columns(Polars.col("values").list.var.alias("var"))
|
|
318
|
+
# # =>
|
|
319
|
+
# # shape: (2, 2)
|
|
320
|
+
# # ┌────────────┬──────┐
|
|
321
|
+
# # │ values ┆ var │
|
|
322
|
+
# # │ --- ┆ --- │
|
|
323
|
+
# # │ list[i64] ┆ f64 │
|
|
324
|
+
# # ╞════════════╪══════╡
|
|
325
|
+
# # │ [-1, 0, 1] ┆ 1.0 │
|
|
326
|
+
# # │ [1, 10] ┆ 40.5 │
|
|
327
|
+
# # └────────────┴──────┘
|
|
328
|
+
def var(ddof: 1)
|
|
329
|
+
Utils.wrap_expr(_rbexpr.list_var(ddof))
|
|
330
|
+
end
|
|
331
|
+
|
|
246
332
|
# Sort the arrays in the list.
|
|
247
333
|
#
|
|
334
|
+
# @param descending [Boolean]
|
|
335
|
+
# Sort in descending order.
|
|
336
|
+
# @param nulls_last [Boolean]
|
|
337
|
+
# Place null values last.
|
|
338
|
+
#
|
|
248
339
|
# @return [Expr]
|
|
249
340
|
#
|
|
250
341
|
# @example
|
|
@@ -264,8 +355,8 @@ module Polars
|
|
|
264
355
|
# # │ [1, 2, 3] │
|
|
265
356
|
# # │ [1, 2, 9] │
|
|
266
357
|
# # └───────────┘
|
|
267
|
-
def sort(
|
|
268
|
-
Utils.wrap_expr(_rbexpr.list_sort(
|
|
358
|
+
def sort(descending: false, nulls_last: false)
|
|
359
|
+
Utils.wrap_expr(_rbexpr.list_sort(descending, nulls_last))
|
|
269
360
|
end
|
|
270
361
|
|
|
271
362
|
# Reverse the arrays in the list.
|
|
@@ -290,7 +381,7 @@ module Polars
|
|
|
290
381
|
# # │ [2, 1, 9] │
|
|
291
382
|
# # └───────────┘
|
|
292
383
|
def reverse
|
|
293
|
-
|
|
384
|
+
eval(F.element.reverse)
|
|
294
385
|
end
|
|
295
386
|
|
|
296
387
|
# Get the unique/distinct values in the list.
|
|
@@ -314,7 +405,32 @@ module Polars
|
|
|
314
405
|
# # │ [1, 2] │
|
|
315
406
|
# # └───────────┘
|
|
316
407
|
def unique(maintain_order: false)
|
|
317
|
-
|
|
408
|
+
eval(F.element.unique(maintain_order: maintain_order))
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
# Count the number of unique values in every sub-lists.
|
|
412
|
+
#
|
|
413
|
+
# @return [Expr]
|
|
414
|
+
#
|
|
415
|
+
# @example
|
|
416
|
+
# df = Polars::DataFrame.new(
|
|
417
|
+
# {
|
|
418
|
+
# "a" => [[1, 1, 2], [2, 3, 4]]
|
|
419
|
+
# }
|
|
420
|
+
# )
|
|
421
|
+
# df.with_columns(n_unique: Polars.col("a").list.n_unique)
|
|
422
|
+
# # =>
|
|
423
|
+
# # shape: (2, 2)
|
|
424
|
+
# # ┌───────────┬──────────┐
|
|
425
|
+
# # │ a ┆ n_unique │
|
|
426
|
+
# # │ --- ┆ --- │
|
|
427
|
+
# # │ list[i64] ┆ u32 │
|
|
428
|
+
# # ╞═══════════╪══════════╡
|
|
429
|
+
# # │ [1, 1, 2] ┆ 2 │
|
|
430
|
+
# # │ [2, 3, 4] ┆ 3 │
|
|
431
|
+
# # └───────────┴──────────┘
|
|
432
|
+
def n_unique
|
|
433
|
+
agg(F.element.n_unique)
|
|
318
434
|
end
|
|
319
435
|
|
|
320
436
|
# Concat the arrays in a Series dtype List in linear time.
|
|
@@ -361,7 +477,7 @@ module Polars
|
|
|
361
477
|
#
|
|
362
478
|
# So index `0` would return the first item of every sublist
|
|
363
479
|
# and index `-1` would return the last item of every sublist
|
|
364
|
-
# if an index is out of bounds, it will return a `
|
|
480
|
+
# if an index is out of bounds, it will return a `nil`.
|
|
365
481
|
#
|
|
366
482
|
# @param index [Integer]
|
|
367
483
|
# Index to return per sublist
|
|
@@ -374,7 +490,7 @@ module Polars
|
|
|
374
490
|
#
|
|
375
491
|
# @example
|
|
376
492
|
# df = Polars::DataFrame.new({"foo" => [[3, 2, 1], [], [1, 2]]})
|
|
377
|
-
# df.select(Polars.col("foo").list.get(0))
|
|
493
|
+
# df.select(Polars.col("foo").list.get(0, null_on_oob: true))
|
|
378
494
|
# # =>
|
|
379
495
|
# # shape: (3, 1)
|
|
380
496
|
# # ┌──────┐
|
|
@@ -386,7 +502,7 @@ module Polars
|
|
|
386
502
|
# # │ null │
|
|
387
503
|
# # │ 1 │
|
|
388
504
|
# # └──────┘
|
|
389
|
-
def get(index, null_on_oob:
|
|
505
|
+
def get(index, null_on_oob: false)
|
|
390
506
|
index = Utils.parse_into_expression(index)
|
|
391
507
|
Utils.wrap_expr(_rbexpr.list_get(index, null_on_oob))
|
|
392
508
|
end
|
|
@@ -403,12 +519,12 @@ module Polars
|
|
|
403
519
|
# The indices may be defined in a single column, or by sublists in another
|
|
404
520
|
# column of dtype `List`.
|
|
405
521
|
#
|
|
406
|
-
# @param
|
|
522
|
+
# @param indices [Object]
|
|
407
523
|
# Indices to return per sublist
|
|
408
524
|
# @param null_on_oob [Boolean]
|
|
409
525
|
# Behavior if an index is out of bounds:
|
|
410
|
-
#
|
|
411
|
-
#
|
|
526
|
+
# true -> set as null
|
|
527
|
+
# false -> raise an error
|
|
412
528
|
# Note that defaulting to raising an error is much cheaper
|
|
413
529
|
#
|
|
414
530
|
# @return [Expr]
|
|
@@ -427,14 +543,52 @@ module Polars
|
|
|
427
543
|
# # │ [] ┆ [null, null] │
|
|
428
544
|
# # │ [1, 2, … 5] ┆ [1, 5] │
|
|
429
545
|
# # └─────────────┴──────────────┘
|
|
430
|
-
def gather(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
546
|
+
def gather(indices, null_on_oob: false)
|
|
547
|
+
indices = Utils.parse_into_expression(indices)
|
|
548
|
+
Utils.wrap_expr(_rbexpr.list_gather(indices, null_on_oob))
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
# Take every n-th value start from offset in sublists.
|
|
552
|
+
#
|
|
553
|
+
# @param n [Integer]
|
|
554
|
+
# Gather every n-th element.
|
|
555
|
+
# @param offset [Integer]
|
|
556
|
+
# Starting index.
|
|
557
|
+
#
|
|
558
|
+
# @return [Expr]
|
|
559
|
+
#
|
|
560
|
+
# @example
|
|
561
|
+
# df = Polars::DataFrame.new(
|
|
562
|
+
# {
|
|
563
|
+
# "a" => [[1, 2, 3, 4, 5], [6, 7, 8], [9, 10, 11, 12]],
|
|
564
|
+
# "n" => [2, 1, 3],
|
|
565
|
+
# "offset" => [0, 1, 0]
|
|
566
|
+
# }
|
|
567
|
+
# )
|
|
568
|
+
# df.with_columns(
|
|
569
|
+
# gather_every: Polars.col("a").list.gather_every(
|
|
570
|
+
# Polars.col("n"), Polars.col("offset")
|
|
571
|
+
# )
|
|
572
|
+
# )
|
|
573
|
+
# # =>
|
|
574
|
+
# # shape: (3, 4)
|
|
575
|
+
# # ┌───────────────┬─────┬────────┬──────────────┐
|
|
576
|
+
# # │ a ┆ n ┆ offset ┆ gather_every │
|
|
577
|
+
# # │ --- ┆ --- ┆ --- ┆ --- │
|
|
578
|
+
# # │ list[i64] ┆ i64 ┆ i64 ┆ list[i64] │
|
|
579
|
+
# # ╞═══════════════╪═════╪════════╪══════════════╡
|
|
580
|
+
# # │ [1, 2, … 5] ┆ 2 ┆ 0 ┆ [1, 3, 5] │
|
|
581
|
+
# # │ [6, 7, 8] ┆ 1 ┆ 1 ┆ [7, 8] │
|
|
582
|
+
# # │ [9, 10, … 12] ┆ 3 ┆ 0 ┆ [9, 12] │
|
|
583
|
+
# # └───────────────┴─────┴────────┴──────────────┘
|
|
584
|
+
def gather_every(
|
|
585
|
+
n,
|
|
586
|
+
offset = 0
|
|
587
|
+
)
|
|
588
|
+
n = Utils.parse_into_expression(n)
|
|
589
|
+
offset = Utils.parse_into_expression(offset)
|
|
590
|
+
Utils.wrap_expr(_rbexpr.list_gather_every(n, offset))
|
|
436
591
|
end
|
|
437
|
-
alias_method :take, :gather
|
|
438
592
|
|
|
439
593
|
# Get the first value of the sublists.
|
|
440
594
|
#
|
|
@@ -455,7 +609,7 @@ module Polars
|
|
|
455
609
|
# # │ 1 │
|
|
456
610
|
# # └──────┘
|
|
457
611
|
def first
|
|
458
|
-
get(0)
|
|
612
|
+
get(0, null_on_oob: true)
|
|
459
613
|
end
|
|
460
614
|
|
|
461
615
|
# Get the last value of the sublists.
|
|
@@ -477,13 +631,57 @@ module Polars
|
|
|
477
631
|
# # │ 2 │
|
|
478
632
|
# # └──────┘
|
|
479
633
|
def last
|
|
480
|
-
get(-1)
|
|
634
|
+
get(-1, null_on_oob: true)
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
# Get the single value of the sublists.
|
|
638
|
+
#
|
|
639
|
+
# This errors if the sublist length is not exactly one.
|
|
640
|
+
#
|
|
641
|
+
# @param allow_empty [Boolean]
|
|
642
|
+
# Allow having no values to return `null`.
|
|
643
|
+
#
|
|
644
|
+
# @return [Expr]
|
|
645
|
+
#
|
|
646
|
+
# @example
|
|
647
|
+
# df = Polars::DataFrame.new({"a" => [[3], [1], [2]]})
|
|
648
|
+
# df.with_columns(item: Polars.col("a").list.item)
|
|
649
|
+
# # =>
|
|
650
|
+
# # shape: (3, 2)
|
|
651
|
+
# # ┌───────────┬──────┐
|
|
652
|
+
# # │ a ┆ item │
|
|
653
|
+
# # │ --- ┆ --- │
|
|
654
|
+
# # │ list[i64] ┆ i64 │
|
|
655
|
+
# # ╞═══════════╪══════╡
|
|
656
|
+
# # │ [3] ┆ 3 │
|
|
657
|
+
# # │ [1] ┆ 1 │
|
|
658
|
+
# # │ [2] ┆ 2 │
|
|
659
|
+
# # └───────────┴──────┘
|
|
660
|
+
#
|
|
661
|
+
# @example
|
|
662
|
+
# df = Polars::DataFrame.new({"a" => [[], [1], [2]]})
|
|
663
|
+
# df.select(Polars.col("a").list.item(allow_empty: true))
|
|
664
|
+
# # =>
|
|
665
|
+
# # shape: (3, 1)
|
|
666
|
+
# # ┌──────┐
|
|
667
|
+
# # │ a │
|
|
668
|
+
# # │ --- │
|
|
669
|
+
# # │ i64 │
|
|
670
|
+
# # ╞══════╡
|
|
671
|
+
# # │ null │
|
|
672
|
+
# # │ 1 │
|
|
673
|
+
# # │ 2 │
|
|
674
|
+
# # └──────┘
|
|
675
|
+
def item(allow_empty: false)
|
|
676
|
+
agg(F.element.item(allow_empty: allow_empty))
|
|
481
677
|
end
|
|
482
678
|
|
|
483
679
|
# Check if sublists contain the given item.
|
|
484
680
|
#
|
|
485
681
|
# @param item [Object]
|
|
486
682
|
# Item that will be checked for membership
|
|
683
|
+
# @param nulls_equal [Boolean]
|
|
684
|
+
# If true, treat null as a distinct value. Null values will not propagate.
|
|
487
685
|
#
|
|
488
686
|
# @return [Expr]
|
|
489
687
|
#
|
|
@@ -501,8 +699,8 @@ module Polars
|
|
|
501
699
|
# # │ false │
|
|
502
700
|
# # │ true │
|
|
503
701
|
# # └───────┘
|
|
504
|
-
def contains(item)
|
|
505
|
-
Utils.wrap_expr(_rbexpr.list_contains(Utils.parse_into_expression(item)))
|
|
702
|
+
def contains(item, nulls_equal: true)
|
|
703
|
+
Utils.wrap_expr(_rbexpr.list_contains(Utils.parse_into_expression(item), nulls_equal))
|
|
506
704
|
end
|
|
507
705
|
|
|
508
706
|
# Join all string items in a sublist and place a separator between them.
|
|
@@ -698,7 +896,37 @@ module Polars
|
|
|
698
896
|
Utils.wrap_expr(_rbexpr.list_tail(n))
|
|
699
897
|
end
|
|
700
898
|
|
|
701
|
-
#
|
|
899
|
+
# Returns a column with a separate row for every list element.
|
|
900
|
+
#
|
|
901
|
+
# @param empty_as_null [Boolean]
|
|
902
|
+
# Explode an empty list into a `null`.
|
|
903
|
+
# @param keep_nulls [Boolean]
|
|
904
|
+
# Explode a `null` list into a `null`.
|
|
905
|
+
#
|
|
906
|
+
# @return [Expr]
|
|
907
|
+
#
|
|
908
|
+
# @example
|
|
909
|
+
# df = Polars::DataFrame.new({"a" => [[1, 2, 3], [4, 5, 6]]})
|
|
910
|
+
# df.select(Polars.col("a").list.explode)
|
|
911
|
+
# # =>
|
|
912
|
+
# # shape: (6, 1)
|
|
913
|
+
# # ┌─────┐
|
|
914
|
+
# # │ a │
|
|
915
|
+
# # │ --- │
|
|
916
|
+
# # │ i64 │
|
|
917
|
+
# # ╞═════╡
|
|
918
|
+
# # │ 1 │
|
|
919
|
+
# # │ 2 │
|
|
920
|
+
# # │ 3 │
|
|
921
|
+
# # │ 4 │
|
|
922
|
+
# # │ 5 │
|
|
923
|
+
# # │ 6 │
|
|
924
|
+
# # └─────┘
|
|
925
|
+
def explode(empty_as_null: true, keep_nulls: true)
|
|
926
|
+
Utils.wrap_expr(_rbexpr.explode(empty_as_null, keep_nulls))
|
|
927
|
+
end
|
|
928
|
+
|
|
929
|
+
# Count how often the value produced by `element` occurs.
|
|
702
930
|
#
|
|
703
931
|
# @param element [Expr]
|
|
704
932
|
# An expression that produces a single value
|
|
@@ -707,7 +935,7 @@ module Polars
|
|
|
707
935
|
#
|
|
708
936
|
# @example
|
|
709
937
|
# df = Polars::DataFrame.new({"listcol" => [[0], [1], [1, 2, 3, 2], [1, 2, 1], [4, 4]]})
|
|
710
|
-
# df.select(Polars.col("listcol").list.
|
|
938
|
+
# df.select(Polars.col("listcol").list.count_matches(2).alias("number_of_twos"))
|
|
711
939
|
# # =>
|
|
712
940
|
# # shape: (5, 1)
|
|
713
941
|
# # ┌────────────────┐
|
|
@@ -724,34 +952,79 @@ module Polars
|
|
|
724
952
|
def count_matches(element)
|
|
725
953
|
Utils.wrap_expr(_rbexpr.list_count_matches(Utils.parse_into_expression(element)))
|
|
726
954
|
end
|
|
727
|
-
|
|
955
|
+
|
|
956
|
+
# Convert a List column into an Array column with the same inner data type.
|
|
957
|
+
#
|
|
958
|
+
# @param width [Integer]
|
|
959
|
+
# Width of the resulting Array column.
|
|
960
|
+
#
|
|
961
|
+
# @return [Expr]
|
|
962
|
+
#
|
|
963
|
+
# @example
|
|
964
|
+
# df = Polars::DataFrame.new(
|
|
965
|
+
# {"a" => [[1, 2], [3, 4]]},
|
|
966
|
+
# schema: {"a" => Polars::List.new(Polars::Int8)}
|
|
967
|
+
# )
|
|
968
|
+
# df.with_columns(array: Polars.col("a").list.to_array(2))
|
|
969
|
+
# # =>
|
|
970
|
+
# # shape: (2, 2)
|
|
971
|
+
# # ┌──────────┬──────────────┐
|
|
972
|
+
# # │ a ┆ array │
|
|
973
|
+
# # │ --- ┆ --- │
|
|
974
|
+
# # │ list[i8] ┆ array[i8, 2] │
|
|
975
|
+
# # ╞══════════╪══════════════╡
|
|
976
|
+
# # │ [1, 2] ┆ [1, 2] │
|
|
977
|
+
# # │ [3, 4] ┆ [3, 4] │
|
|
978
|
+
# # └──────────┴──────────────┘
|
|
979
|
+
def to_array(width)
|
|
980
|
+
Utils.wrap_expr(_rbexpr.list_to_array(width))
|
|
981
|
+
end
|
|
728
982
|
|
|
729
983
|
# Convert the series of type `List` to a series of type `Struct`.
|
|
730
984
|
#
|
|
731
985
|
# @param n_field_strategy ["first_non_null", "max_width"]
|
|
732
|
-
#
|
|
733
|
-
# @param
|
|
734
|
-
#
|
|
735
|
-
#
|
|
986
|
+
# Deprecated and ignored.
|
|
987
|
+
# @param fields pArray
|
|
988
|
+
# If the name and number of the desired fields is known in advance
|
|
989
|
+
# a list of field names can be given, which will be assigned by index.
|
|
990
|
+
# Otherwise, to dynamically assign field names, a custom function can be
|
|
991
|
+
# used; if neither are set, fields will be `field_0, field_1 .. field_n`.
|
|
992
|
+
# @param upper_bound [Object]
|
|
993
|
+
# A polars `LazyFrame` needs to know the schema at all times, so the
|
|
994
|
+
# caller must provide an upper bound of the number of struct fields that
|
|
995
|
+
# will be created; if set incorrectly, subsequent operations may fail.
|
|
996
|
+
# (For example, an `all.sum` expression will look in the current
|
|
997
|
+
# schema to determine which columns to select).
|
|
998
|
+
#
|
|
999
|
+
# When operating on a `DataFrame`, the schema does not need to be
|
|
1000
|
+
# tracked or pre-determined, as the result will be eagerly evaluated,
|
|
1001
|
+
# so you can leave this parameter unset.
|
|
736
1002
|
#
|
|
737
1003
|
# @return [Expr]
|
|
738
1004
|
#
|
|
739
1005
|
# @example
|
|
740
|
-
# df = Polars::DataFrame.new({"
|
|
741
|
-
# df.
|
|
1006
|
+
# df = Polars::DataFrame.new({"n" => [[0, 1], [0, 1, 2]]})
|
|
1007
|
+
# df.with_columns(struct: Polars.col("n").list.to_struct(upper_bound: 2))
|
|
742
1008
|
# # =>
|
|
743
|
-
# # shape: (2,
|
|
744
|
-
# #
|
|
745
|
-
# # │
|
|
746
|
-
# # │ ---
|
|
747
|
-
# # │ struct[
|
|
748
|
-
# #
|
|
749
|
-
# # │ {1
|
|
750
|
-
# # │
|
|
751
|
-
# #
|
|
752
|
-
def to_struct(n_field_strategy:
|
|
753
|
-
|
|
754
|
-
|
|
1009
|
+
# # shape: (2, 2)
|
|
1010
|
+
# # ┌───────────┬───────────┐
|
|
1011
|
+
# # │ n ┆ struct │
|
|
1012
|
+
# # │ --- ┆ --- │
|
|
1013
|
+
# # │ list[i64] ┆ struct[2] │
|
|
1014
|
+
# # ╞═══════════╪═══════════╡
|
|
1015
|
+
# # │ [0, 1] ┆ {0,1} │
|
|
1016
|
+
# # │ [0, 1, 2] ┆ {0,1} │
|
|
1017
|
+
# # └───────────┴───────────┘
|
|
1018
|
+
def to_struct(n_field_strategy: nil, fields: nil, upper_bound: nil)
|
|
1019
|
+
if !fields.is_a?(::Array)
|
|
1020
|
+
if fields.nil?
|
|
1021
|
+
fields = upper_bound.times.map { |i| "field_#{i}" }
|
|
1022
|
+
else
|
|
1023
|
+
fields = upper_bound.times.map { |i| fields.(i) }
|
|
1024
|
+
end
|
|
1025
|
+
end
|
|
1026
|
+
|
|
1027
|
+
Utils.wrap_expr(_rbexpr.list_to_struct(fields))
|
|
755
1028
|
end
|
|
756
1029
|
|
|
757
1030
|
# Run any polars expression against the lists' elements.
|
|
@@ -759,18 +1032,12 @@ module Polars
|
|
|
759
1032
|
# @param expr [Expr]
|
|
760
1033
|
# Expression to run. Note that you can select an element with `Polars.first`, or
|
|
761
1034
|
# `Polars.col`
|
|
762
|
-
# @param parallel [Boolean]
|
|
763
|
-
# Run all expression parallel. Don't activate this blindly.
|
|
764
|
-
# Parallelism is worth it if there is enough work to do per thread.
|
|
765
|
-
#
|
|
766
|
-
# This likely should not be use in the group by context, because we already
|
|
767
|
-
# parallel execution per group
|
|
768
1035
|
#
|
|
769
1036
|
# @return [Expr]
|
|
770
1037
|
#
|
|
771
1038
|
# @example
|
|
772
1039
|
# df = Polars::DataFrame.new({"a" => [1, 8, 3], "b" => [4, 5, 2]})
|
|
773
|
-
# df.
|
|
1040
|
+
# df.with_columns(
|
|
774
1041
|
# Polars.concat_list(["a", "b"]).list.eval(Polars.element.rank).alias("rank")
|
|
775
1042
|
# )
|
|
776
1043
|
# # =>
|
|
@@ -784,8 +1051,233 @@ module Polars
|
|
|
784
1051
|
# # │ 8 ┆ 5 ┆ [2.0, 1.0] │
|
|
785
1052
|
# # │ 3 ┆ 2 ┆ [2.0, 1.0] │
|
|
786
1053
|
# # └─────┴─────┴────────────┘
|
|
787
|
-
def eval(expr
|
|
788
|
-
Utils.wrap_expr(_rbexpr.list_eval(expr._rbexpr
|
|
1054
|
+
def eval(expr)
|
|
1055
|
+
Utils.wrap_expr(_rbexpr.list_eval(expr._rbexpr))
|
|
1056
|
+
end
|
|
1057
|
+
|
|
1058
|
+
# Run any polars aggregation expression against the lists' elements.
|
|
1059
|
+
#
|
|
1060
|
+
# @param expr [Expr]
|
|
1061
|
+
# Expression to run. Note that you can select an element with `Polars.element`.
|
|
1062
|
+
#
|
|
1063
|
+
# @return [Expr]
|
|
1064
|
+
#
|
|
1065
|
+
# @example
|
|
1066
|
+
# df = Polars::DataFrame.new({"a" => [[1, nil], [42, 13], [nil, nil]]})
|
|
1067
|
+
# df.with_columns(null_count: Polars.col("a").list.agg(Polars.element.null_count))
|
|
1068
|
+
# # =>
|
|
1069
|
+
# # shape: (3, 2)
|
|
1070
|
+
# # ┌──────────────┬────────────┐
|
|
1071
|
+
# # │ a ┆ null_count │
|
|
1072
|
+
# # │ --- ┆ --- │
|
|
1073
|
+
# # │ list[i64] ┆ u32 │
|
|
1074
|
+
# # ╞══════════════╪════════════╡
|
|
1075
|
+
# # │ [1, null] ┆ 1 │
|
|
1076
|
+
# # │ [42, 13] ┆ 0 │
|
|
1077
|
+
# # │ [null, null] ┆ 2 │
|
|
1078
|
+
# # └──────────────┴────────────┘
|
|
1079
|
+
#
|
|
1080
|
+
# @example
|
|
1081
|
+
# df.with_columns(no_nulls: Polars.col("a").list.agg(Polars.element.drop_nulls))
|
|
1082
|
+
# # =>
|
|
1083
|
+
# # shape: (3, 2)
|
|
1084
|
+
# # ┌──────────────┬───────────┐
|
|
1085
|
+
# # │ a ┆ no_nulls │
|
|
1086
|
+
# # │ --- ┆ --- │
|
|
1087
|
+
# # │ list[i64] ┆ list[i64] │
|
|
1088
|
+
# # ╞══════════════╪═══════════╡
|
|
1089
|
+
# # │ [1, null] ┆ [1] │
|
|
1090
|
+
# # │ [42, 13] ┆ [42, 13] │
|
|
1091
|
+
# # │ [null, null] ┆ [] │
|
|
1092
|
+
# # └──────────────┴───────────┘
|
|
1093
|
+
def agg(expr)
|
|
1094
|
+
Utils.wrap_expr(_rbexpr.list_agg(expr._rbexpr))
|
|
1095
|
+
end
|
|
1096
|
+
|
|
1097
|
+
# Filter elements in each list by a boolean expression.
|
|
1098
|
+
#
|
|
1099
|
+
# @param predicate [Object]
|
|
1100
|
+
# A boolean expression that is evaluated per list element.
|
|
1101
|
+
# You can refer to the current element with `Polars.element`.
|
|
1102
|
+
#
|
|
1103
|
+
# @return [Expr]
|
|
1104
|
+
#
|
|
1105
|
+
# @example
|
|
1106
|
+
# df = Polars::DataFrame.new({"a" => [1, 8, 3], "b" => [4, 5, 2]})
|
|
1107
|
+
# df.with_columns(
|
|
1108
|
+
# evens: Polars.concat_list("a", "b").list.filter(Polars.element % 2 == 0)
|
|
1109
|
+
# )
|
|
1110
|
+
# # =>
|
|
1111
|
+
# # shape: (3, 3)
|
|
1112
|
+
# # ┌─────┬─────┬───────────┐
|
|
1113
|
+
# # │ a ┆ b ┆ evens │
|
|
1114
|
+
# # │ --- ┆ --- ┆ --- │
|
|
1115
|
+
# # │ i64 ┆ i64 ┆ list[i64] │
|
|
1116
|
+
# # ╞═════╪═════╪═══════════╡
|
|
1117
|
+
# # │ 1 ┆ 4 ┆ [4] │
|
|
1118
|
+
# # │ 8 ┆ 5 ┆ [8] │
|
|
1119
|
+
# # │ 3 ┆ 2 ┆ [2] │
|
|
1120
|
+
# # └─────┴─────┴───────────┘
|
|
1121
|
+
def filter(predicate)
|
|
1122
|
+
Utils.wrap_expr(_rbexpr.list_filter(predicate._rbexpr))
|
|
1123
|
+
end
|
|
1124
|
+
|
|
1125
|
+
# Compute the SET UNION between the elements in this list and the elements of `other`.
|
|
1126
|
+
#
|
|
1127
|
+
# @param other [Object]
|
|
1128
|
+
# Right hand side of the set operation.
|
|
1129
|
+
#
|
|
1130
|
+
# @return [Expr]
|
|
1131
|
+
#
|
|
1132
|
+
# @example
|
|
1133
|
+
# df = Polars::DataFrame.new(
|
|
1134
|
+
# {
|
|
1135
|
+
# "a" => [[1, 2, 3], [], [nil, 3], [5, 6, 7]],
|
|
1136
|
+
# "b" => [[2, 3, 4], [3], [3, 4, nil], [6, 8]]
|
|
1137
|
+
# }
|
|
1138
|
+
# )
|
|
1139
|
+
# df.with_columns(
|
|
1140
|
+
# union: Polars.col("a").list.set_union("b")
|
|
1141
|
+
# )
|
|
1142
|
+
# # =>
|
|
1143
|
+
# # shape: (4, 3)
|
|
1144
|
+
# # ┌───────────┬──────────────┬──────────────┐
|
|
1145
|
+
# # │ a ┆ b ┆ union │
|
|
1146
|
+
# # │ --- ┆ --- ┆ --- │
|
|
1147
|
+
# # │ list[i64] ┆ list[i64] ┆ list[i64] │
|
|
1148
|
+
# # ╞═══════════╪══════════════╪══════════════╡
|
|
1149
|
+
# # │ [1, 2, 3] ┆ [2, 3, 4] ┆ [1, 2, … 4] │
|
|
1150
|
+
# # │ [] ┆ [3] ┆ [3] │
|
|
1151
|
+
# # │ [null, 3] ┆ [3, 4, null] ┆ [null, 3, 4] │
|
|
1152
|
+
# # │ [5, 6, 7] ┆ [6, 8] ┆ [5, 6, … 8] │
|
|
1153
|
+
# # └───────────┴──────────────┴──────────────┘
|
|
1154
|
+
def set_union(other)
|
|
1155
|
+
if other.respond_to?(:each)
|
|
1156
|
+
if !other.is_a?(::Array) && !other.is_a?(Series) && !other.is_a?(DataFrame)
|
|
1157
|
+
other = other.to_a
|
|
1158
|
+
end
|
|
1159
|
+
other = F.lit(other)._rbexpr
|
|
1160
|
+
else
|
|
1161
|
+
other = Utils.parse_into_expression(other)
|
|
1162
|
+
end
|
|
1163
|
+
Utils.wrap_expr(_rbexpr.list_set_operation(other, "union"))
|
|
1164
|
+
end
|
|
1165
|
+
|
|
1166
|
+
# Compute the SET DIFFERENCE between the elements in this list and the elements of `other`.
|
|
1167
|
+
#
|
|
1168
|
+
# @param other [Object]
|
|
1169
|
+
# Right hand side of the set operation.
|
|
1170
|
+
#
|
|
1171
|
+
# @return [Expr]
|
|
1172
|
+
#
|
|
1173
|
+
# @example
|
|
1174
|
+
# df = Polars::DataFrame.new(
|
|
1175
|
+
# {
|
|
1176
|
+
# "a" => [[1, 2, 3], [], [nil, 3], [5, 6, 7]],
|
|
1177
|
+
# "b" => [[2, 3, 4], [3], [3, 4, nil], [6, 8]]
|
|
1178
|
+
# }
|
|
1179
|
+
# )
|
|
1180
|
+
# df.with_columns(difference: Polars.col("a").list.set_difference("b"))
|
|
1181
|
+
# # =>
|
|
1182
|
+
# # shape: (4, 3)
|
|
1183
|
+
# # ┌───────────┬──────────────┬────────────┐
|
|
1184
|
+
# # │ a ┆ b ┆ difference │
|
|
1185
|
+
# # │ --- ┆ --- ┆ --- │
|
|
1186
|
+
# # │ list[i64] ┆ list[i64] ┆ list[i64] │
|
|
1187
|
+
# # ╞═══════════╪══════════════╪════════════╡
|
|
1188
|
+
# # │ [1, 2, 3] ┆ [2, 3, 4] ┆ [1] │
|
|
1189
|
+
# # │ [] ┆ [3] ┆ [] │
|
|
1190
|
+
# # │ [null, 3] ┆ [3, 4, null] ┆ [] │
|
|
1191
|
+
# # │ [5, 6, 7] ┆ [6, 8] ┆ [5, 7] │
|
|
1192
|
+
# # └───────────┴──────────────┴────────────┘
|
|
1193
|
+
def set_difference(other)
|
|
1194
|
+
if other.respond_to?(:each)
|
|
1195
|
+
if !other.is_a?(::Array) && !other.is_a?(Series) && !other.is_a?(DataFrame)
|
|
1196
|
+
other = other.to_a
|
|
1197
|
+
end
|
|
1198
|
+
other = F.lit(other)._rbexpr
|
|
1199
|
+
else
|
|
1200
|
+
other = Utils.parse_into_expression(other)
|
|
1201
|
+
end
|
|
1202
|
+
Utils.wrap_expr(_rbexpr.list_set_operation(other, "difference"))
|
|
1203
|
+
end
|
|
1204
|
+
|
|
1205
|
+
# Compute the SET INTERSECTION between the elements in this list and the elements of `other`.
|
|
1206
|
+
#
|
|
1207
|
+
# @param other [Object]
|
|
1208
|
+
# Right hand side of the set operation.
|
|
1209
|
+
#
|
|
1210
|
+
# @return [Expr]
|
|
1211
|
+
#
|
|
1212
|
+
# @example
|
|
1213
|
+
# df = Polars::DataFrame.new(
|
|
1214
|
+
# {
|
|
1215
|
+
# "a" => [[1, 2, 3], [], [nil, 3], [5, 6, 7]],
|
|
1216
|
+
# "b" => [[2, 3, 4], [3], [3, 4, nil], [6, 8]]
|
|
1217
|
+
# }
|
|
1218
|
+
# )
|
|
1219
|
+
# df.with_columns(intersection: Polars.col("a").list.set_intersection("b"))
|
|
1220
|
+
# # =>
|
|
1221
|
+
# # shape: (4, 3)
|
|
1222
|
+
# # ┌───────────┬──────────────┬──────────────┐
|
|
1223
|
+
# # │ a ┆ b ┆ intersection │
|
|
1224
|
+
# # │ --- ┆ --- ┆ --- │
|
|
1225
|
+
# # │ list[i64] ┆ list[i64] ┆ list[i64] │
|
|
1226
|
+
# # ╞═══════════╪══════════════╪══════════════╡
|
|
1227
|
+
# # │ [1, 2, 3] ┆ [2, 3, 4] ┆ [2, 3] │
|
|
1228
|
+
# # │ [] ┆ [3] ┆ [] │
|
|
1229
|
+
# # │ [null, 3] ┆ [3, 4, null] ┆ [null, 3] │
|
|
1230
|
+
# # │ [5, 6, 7] ┆ [6, 8] ┆ [6] │
|
|
1231
|
+
# # └───────────┴──────────────┴──────────────┘
|
|
1232
|
+
def set_intersection(other)
|
|
1233
|
+
if other.respond_to?(:each)
|
|
1234
|
+
if !other.is_a?(::Array) && !other.is_a?(Series) && !other.is_a?(DataFrame)
|
|
1235
|
+
other = other.to_a
|
|
1236
|
+
end
|
|
1237
|
+
other = F.lit(other)._rbexpr
|
|
1238
|
+
else
|
|
1239
|
+
other = Utils.parse_into_expression(other)
|
|
1240
|
+
end
|
|
1241
|
+
Utils.wrap_expr(_rbexpr.list_set_operation(other, "intersection"))
|
|
1242
|
+
end
|
|
1243
|
+
|
|
1244
|
+
# Compute the SET SYMMETRIC DIFFERENCE between the elements in this list and the elements of `other`.
|
|
1245
|
+
#
|
|
1246
|
+
# @param other [Object]
|
|
1247
|
+
# Right hand side of the set operation.
|
|
1248
|
+
#
|
|
1249
|
+
# @return [Expr]
|
|
1250
|
+
#
|
|
1251
|
+
# @example
|
|
1252
|
+
# df = Polars::DataFrame.new(
|
|
1253
|
+
# {
|
|
1254
|
+
# "a" => [[1, 2, 3], [], [nil, 3], [5, 6, 7]],
|
|
1255
|
+
# "b" => [[2, 3, 4], [3], [3, 4, nil], [6, 8]]
|
|
1256
|
+
# }
|
|
1257
|
+
# )
|
|
1258
|
+
# df.with_columns(sdiff: Polars.col("b").list.set_symmetric_difference("a"))
|
|
1259
|
+
# # =>
|
|
1260
|
+
# # shape: (4, 3)
|
|
1261
|
+
# # ┌───────────┬──────────────┬───────────┐
|
|
1262
|
+
# # │ a ┆ b ┆ sdiff │
|
|
1263
|
+
# # │ --- ┆ --- ┆ --- │
|
|
1264
|
+
# # │ list[i64] ┆ list[i64] ┆ list[i64] │
|
|
1265
|
+
# # ╞═══════════╪══════════════╪═══════════╡
|
|
1266
|
+
# # │ [1, 2, 3] ┆ [2, 3, 4] ┆ [4, 1] │
|
|
1267
|
+
# # │ [] ┆ [3] ┆ [3] │
|
|
1268
|
+
# # │ [null, 3] ┆ [3, 4, null] ┆ [4] │
|
|
1269
|
+
# # │ [5, 6, 7] ┆ [6, 8] ┆ [8, 5, 7] │
|
|
1270
|
+
# # └───────────┴──────────────┴───────────┘
|
|
1271
|
+
def set_symmetric_difference(other)
|
|
1272
|
+
if other.respond_to?(:each)
|
|
1273
|
+
if !other.is_a?(::Array) && !other.is_a?(Series) && !other.is_a?(DataFrame)
|
|
1274
|
+
other = other.to_a
|
|
1275
|
+
end
|
|
1276
|
+
other = F.lit(other)._rbexpr
|
|
1277
|
+
else
|
|
1278
|
+
other = Utils.parse_into_expression(other)
|
|
1279
|
+
end
|
|
1280
|
+
Utils.wrap_expr(_rbexpr.list_set_operation(other, "symmetric_difference"))
|
|
789
1281
|
end
|
|
790
1282
|
end
|
|
791
1283
|
end
|