module Polars
# Series.list namespace.
class ListNameSpace
include ExprDispatch
self._accessor = "list"
# @private
def initialize(series)
self._s = series._s
end
# Evaluate whether all boolean values in a list are true.
#
# @return [Series]
#
# @example
# s = Polars::Series.new(
# [[true, true], [false, true], [false, false], [nil], [], nil],
# dtype: Polars::List.new(Polars::Boolean)
# )
# s.list.all
# # =>
# # shape: (6,)
# # Series: '' [bool]
# # [
# # true
# # false
# # false
# # true
# # true
# # null
# # ]
def all
super
end
# Evaluate whether any boolean value in a list is true.
#
# @return [Series]
#
# @example
# s = Polars::Series.new(
# [[true, true], [false, true], [false, false], [nil], [], nil],
# dtype: Polars::List.new(Polars::Boolean)
# )
# s.list.any
# # =>
# # shape: (6,)
# # Series: '' [bool]
# # [
# # true
# # true
# # false
# # false
# # false
# # null
# # ]
def any
super
end
# Get the length of the arrays as UInt32.
#
# @return [Series]
#
# @example
# s = Polars::Series.new([[1, 2, 3], [5]])
# s.list.len
# # =>
# # shape: (2,)
# # Series: '' [u32]
# # [
# # 3
# # 1
# # ]
def len
super
end
# Drop all null values in the list.
#
# The original order of the remaining elements is preserved.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("values", [[nil, 1, nil, 2], [nil], [3, 4]])
# s.list.drop_nulls
# # =>
# # shape: (3,)
# # Series: 'values' [list[i64]]
# # [
# # [1, 2]
# # []
# # [3, 4]
# # ]
def drop_nulls
super
end
# Sample from this list.
#
# @param n [Integer]
# Number of items to return. Cannot be used with `fraction`. Defaults to 1 if
# `fraction` is nil.
# @param fraction [Float]
# Fraction of items to return. Cannot be used with `n`.
# @param with_replacement [Boolean]
# Allow values to be sampled more than once.
# @param shuffle [Boolean]
# Shuffle the order of sampled data points.
# @param seed [Integer]
# Seed for the random number generator. If set to nil (default), a
# random seed is generated for each sample operation.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("values", [[1, 2, 3], [4, 5]])
# s.list.sample(n: Polars::Series.new("n", [2, 1]), seed: 1)
# # =>
# # shape: (2,)
# # Series: 'values' [list[i64]]
# # [
# # [2, 3]
# # [5]
# # ]
def sample(n: nil, fraction: nil, with_replacement: false, shuffle: false, seed: nil)
super
end
# Sum all the arrays in the list.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("values", [[1], [2, 3]])
# s.list.sum
# # =>
# # shape: (2,)
# # Series: 'values' [i64]
# # [
# # 1
# # 5
# # ]
def sum
super
end
# Compute the max value of the arrays in the list.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("values", [[4, 1], [2, 3]])
# s.list.max
# # =>
# # shape: (2,)
# # Series: 'values' [i64]
# # [
# # 4
# # 3
# # ]
def max
super
end
# Compute the min value of the arrays in the list.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("values", [[4, 1], [2, 3]])
# s.list.min
# # =>
# # shape: (2,)
# # Series: 'values' [i64]
# # [
# # 1
# # 2
# # ]
def min
super
end
# Compute the mean value of the arrays in the list.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("values", [[3, 1], [3, 3]])
# s.list.mean
# # =>
# # shape: (2,)
# # Series: 'values' [f64]
# # [
# # 2.0
# # 3.0
# # ]
def mean
super
end
# Compute the median value of the arrays in the list.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("values", [[-1, 0, 1], [1, 10]])
# s.list.median
# # =>
# # shape: (2,)
# # Series: 'values' [f64]
# # [
# # 0.0
# # 5.5
# # ]
def median
super
end
# Compute the std value of the arrays in the list.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("values", [[-1, 0, 1], [1, 10]])
# s.list.std
# # =>
# # shape: (2,)
# # Series: 'values' [f64]
# # [
# # 1.0
# # 6.363961
# # ]
def std(ddof: 1)
super
end
# Compute the var value of the arrays in the list.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("values", [[-1, 0, 1], [1, 10]])
# s.list.var
# # =>
# # shape: (2,)
# # Series: 'values' [f64]
# # [
# # 1.0
# # 40.5
# # ]
def var(ddof: 1)
super
end
# Sort the arrays in the list.
#
# @param descending [Boolean]
# Sort in descending order.
# @param nulls_last [Boolean]
# Place null values last.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[3, 2, 1], [9, 1, 2]])
# s.list.sort
# # =>
# # shape: (2,)
# # Series: 'a' [list[i64]]
# # [
# # [1, 2, 3]
# # [1, 2, 9]
# # ]
#
# @example
# s.list.sort(descending: true)
# # =>
# # shape: (2,)
# # Series: 'a' [list[i64]]
# # [
# # [3, 2, 1]
# # [9, 2, 1]
# # ]
def sort(descending: false, nulls_last: false)
super
end
# Reverse the arrays in the list.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[3, 2, 1], [9, 1, 2]])
# s.list.reverse
# # =>
# # shape: (2,)
# # Series: 'a' [list[i64]]
# # [
# # [1, 2, 3]
# # [2, 1, 9]
# # ]
def reverse
super
end
# Get the unique/distinct values in the list.
#
# @param maintain_order [Boolean]
# Maintain order of data. This requires more work.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 1, 2], [2, 3, 3]])
# s.list.unique
# # =>
# # shape: (2,)
# # Series: 'a' [list[i64]]
# # [
# # [1, 2]
# # [2, 3]
# # ]
def unique(maintain_order: false)
super
end
# Count the number of unique values in every sub-lists.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 1, 2], [2, 3, 4]])
# s.list.n_unique
# # =>
# # shape: (2,)
# # Series: 'a' [u32]
# # [
# # 2
# # 3
# # ]
def n_unique
super
end
# Concat the arrays in a Series dtype List in linear time.
#
# @param other [Object]
# Columns to concat into a List Series
#
# @return [Series]
#
# @example
# s1 = Polars::Series.new("a", [["a", "b"], ["c"]])
# s2 = Polars::Series.new("b", [["c"], ["d", nil]])
# s1.list.concat(s2)
# # =>
# # shape: (2,)
# # Series: 'a' [list[str]]
# # [
# # ["a", "b", "c"]
# # ["c", "d", null]
# # ]
def concat(other)
super
end
# Get the value by index in the sublists.
#
# So index `0` would return the first item of every sublist
# and index `-1` would return the last item of every sublist
# if an index is out of bounds, it will return a `nil`.
#
# @param index [Integer]
# Index to return per sublist
# @param null_on_oob [Boolean]
# Behavior if an index is out of bounds:
# true -> set as null
# false -> raise an error
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[3, 2, 1], [], [1, 2]])
# s.list.get(0, null_on_oob: true)
# # =>
# # shape: (3,)
# # Series: 'a' [i64]
# # [
# # 3
# # null
# # 1
# # ]
def get(index, null_on_oob: false)
super
end
# Take sublists by multiple indices.
#
# The indices may be defined in a single column, or by sublists in another
# column of dtype `List`.
#
# @param indices [Object]
# Indices to return per sublist
# @param null_on_oob [Boolean]
# Behavior if an index is out of bounds:
# true -> set as null
# false -> raise an error
# Note that defaulting to raising an error is much cheaper
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[3, 2, 1], [], [1, 2]])
# s.list.gather([0, 2], null_on_oob: true)
# # =>
# # shape: (3,)
# # Series: 'a' [list[i64]]
# # [
# # [3, 1]
# # [null, null]
# # [1, null]
# # ]
def gather(
indices,
null_on_oob: false
)
super
end
# Take every n-th value start from offset in sublists.
#
# @param n [Integer]
# Gather every n-th element.
# @param offset [Integer]
# Starting index.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 2, 3], [], [6, 7, 8, 9]])
# s.list.gather_every(2, 1)
# # =>
# # shape: (3,)
# # Series: 'a' [list[i64]]
# # [
# # [2]
# # []
# # [7, 9]
# # ]
def gather_every(n, offset = 0)
super
end
# Get the value by index in the sublists.
#
# @return [Series]
def [](item)
get(item)
end
# Join all string items in a sublist and place a separator between them.
#
# This errors if inner type of list `!= Utf8`.
#
# @param separator [String]
# string to separate the items with
# @param ignore_nulls [Boolean]
# Ignore null values (default).
#
# If set to `false`, null values will be propagated.
# If the sub-list contains any null values, the output is `nil`.
#
# @return [Series]
#
# @example
# s = Polars::Series.new([["foo", "bar"], ["hello", "world"]])
# s.list.join("-")
# # =>
# # shape: (2,)
# # Series: '' [str]
# # [
# # "foo-bar"
# # "hello-world"
# # ]
def join(separator, ignore_nulls: true)
super
end
# Get the first value of the sublists.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[3, 2, 1], [], [1, 2]])
# s.list.first
# # =>
# # shape: (3,)
# # Series: 'a' [i64]
# # [
# # 3
# # null
# # 1
# # ]
def first
super
end
# Get the last value of the sublists.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[3, 2, 1], [], [1, 2]])
# s.list.last
# # =>
# # shape: (3,)
# # Series: 'a' [i64]
# # [
# # 1
# # null
# # 2
# # ]
def last
super
end
# Get the single value of the sublists.
#
# This errors if the sublist length is not exactly one.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1], [4], [6]])
# s.list.item
# # =>
# # shape: (3,)
# # Series: 'a' [i64]
# # [
# # 1
# # 4
# # 6
# # ]
def item
super
end
# Check if sublists contain the given item.
#
# @param item [Object]
# Item that will be checked for membership.
# @param nulls_equal [Boolean]
# If true, treat null as a distinct value. Null values will not propagate.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[3, 2, 1], [], [1, 2]])
# s.list.contains(1)
# # =>
# # shape: (3,)
# # Series: 'a' [bool]
# # [
# # true
# # false
# # true
# # ]
def contains(item, nulls_equal: true)
super
end
# Retrieve the index of the minimal value in every sublist.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 2], [2, 1]])
# s.list.arg_min
# # =>
# # shape: (2,)
# # Series: 'a' [u32]
# # [
# # 0
# # 1
# # ]
def arg_min
super
end
# Retrieve the index of the maximum value in every sublist.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 2], [2, 1]])
# s.list.arg_max
# # =>
# # shape: (2,)
# # Series: 'a' [u32]
# # [
# # 1
# # 0
# # ]
def arg_max
super
end
# Calculate the n-th discrete difference of every sublist.
#
# @param n [Integer]
# Number of slots to shift.
# @param null_behavior ["ignore", "drop"]
# How to handle null values.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 2, 3, 4], [10, 2, 1]])
# s.list.diff
# # =>
# # shape: (2,)
# # Series: 'a' [list[i64]]
# # [
# # [null, 1, … 1]
# # [null, -8, -1]
# # ]
def diff(n: 1, null_behavior: "ignore")
super
end
# Shift values by the given period.
#
# @param n [Integer]
# Number of places to shift (may be negative).
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 2, 3, 4], [10, 2, 1]])
# s.list.shift
# # =>
# # shape: (2,)
# # Series: 'a' [list[i64]]
# # [
# # [null, 1, … 3]
# # [null, 10, 2]
# # ]
def shift(n = 1)
super
end
# Slice every sublist.
#
# @param offset [Integer]
# Start index. Negative indexing is supported.
# @param length [Integer]
# Length of the slice. If set to `nil` (default), the slice is taken to the
# end of the list.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 2, 3, 4], [10, 2, 1]])
# s.list.slice(1, 2)
# # =>
# # shape: (2,)
# # Series: 'a' [list[i64]]
# # [
# # [2, 3]
# # [2, 1]
# # ]
def slice(offset, length = nil)
super
end
# Slice the first `n` values of every sublist.
#
# @param n [Integer]
# Number of values to return for each sublist.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 2, 3, 4], [10, 2, 1]])
# s.list.head(2)
# # =>
# # shape: (2,)
# # Series: 'a' [list[i64]]
# # [
# # [1, 2]
# # [10, 2]
# # ]
def head(n = 5)
super
end
# Slice the last `n` values of every sublist.
#
# @param n [Integer]
# Number of values to return for each sublist.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 2, 3, 4], [10, 2, 1]])
# s.list.tail(2)
# # =>
# # shape: (2,)
# # Series: 'a' [list[i64]]
# # [
# # [3, 4]
# # [2, 1]
# # ]
def tail(n = 5)
super
end
# Returns a column with a separate row for every list element.
#
# @param empty_as_null [Boolean]
# Explode an empty list into a `null`.
# @param keep_nulls [Boolean]
# Explode a `null` list into a `null`.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 2, 3], [4, 5, 6]])
# s.list.explode
# # =>
# # shape: (6,)
# # Series: 'a' [i64]
# # [
# # 1
# # 2
# # 3
# # 4
# # 5
# # 6
# # ]
def explode(empty_as_null: true, keep_nulls: true)
super
end
# Count how often the value produced by `element` occurs.
#
# @param element [Object]
# An expression that produces a single value
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[0], [1], [1, 2, 3, 2], [1, 2, 1], [4, 4]])
# s.list.count_matches(1)
# # =>
# # shape: (5,)
# # Series: 'a' [u32]
# # [
# # 0
# # 1
# # 1
# # 2
# # 0
# # ]
def count_matches(element)
super
end
# Convert a List column into an Array column with the same inner data type.
#
# @param width [Integer]
# Width of the resulting Array column.
#
# @return [Series]
#
# @example
# s = Polars::Series.new([[1, 2], [3, 4]], dtype: Polars::List.new(Polars::Int8))
# s.list.to_array(2)
# # =>
# # shape: (2,)
# # Series: '' [array[i8, 2]]
# # [
# # [1, 2]
# # [3, 4]
# # ]
def to_array(width)
super
end
# Convert the series of type `List` to a series of type `Struct`.
#
# @param n_field_strategy ["first_non_null", "max_width"]
# Strategy to determine the number of fields of the struct.
# @param fields [Object]
# If the name and number of the desired fields is known in advance
# a list of field names can be given, which will be assigned by index.
# Otherwise, to dynamically assign field names, a custom function can be
# used; if neither are set, fields will be `field_0, field_1 .. field_n`.
#
# @return [Series]
#
# @example Convert list to struct with field name assignment by index from a list of names:
# s1 = Polars::Series.new("n", [[0, 1, 2], [0, 1]])
# s2 = s1.list.to_struct
# s2.struct.fields
# # => ["field_0", "field_1", "field_2"]
#
# @example Convert list to struct with field name assignment by function/index:
# s3 = s1.list.to_struct(fields: ->(idx) { "n%02d" % idx })
# s3.struct.fields
# # => ["n00", "n01", "n02"]
#
# @example Convert list to struct with field name assignment by index from a list of names:
# s1.list.to_struct(fields: ["one", "two", "three"]).struct.unnest
# # =>
# # shape: (2, 3)
# # ┌─────┬─────┬───────┐
# # │ one ┆ two ┆ three │
# # │ --- ┆ --- ┆ --- │
# # │ i64 ┆ i64 ┆ i64 │
# # ╞═════╪═════╪═══════╡
# # │ 0 ┆ 1 ┆ 2 │
# # │ 0 ┆ 1 ┆ null │
# # └─────┴─────┴───────┘
def to_struct(n_field_strategy: "first_non_null", fields: nil)
if fields.is_a?(::Array)
s = Utils.wrap_s(_s)
return (
s.to_frame
.select_seq(F.col(s.name).list.to_struct(fields: fields))
.to_series
)
end
Utils.wrap_s(_s.list_to_struct(n_field_strategy, fields))
end
# Run any polars expression against the lists' elements.
#
# @param expr [Expr]
# Expression to run. Note that you can select an element with `Polars.first`, or
# `Polars.col`
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 4], [8, 5], [3, 2]])
# s.list.eval(Polars.element.rank)
# # =>
# # shape: (3,)
# # Series: 'a' [list[f64]]
# # [
# # [1.0, 2.0]
# # [2.0, 1.0]
# # [2.0, 1.0]
# # ]
def eval(expr)
s = Utils.wrap_s(_s)
s.to_frame.select(F.col(s.name).list.eval(expr)).to_series
end
# Run any polars aggregation expression against the list' elements.
#
# @param expr [Expr]
# Expression to run. Note that you can select an element with `Polars.element`.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, nil], [42, 13], [nil, nil]])
# s.list.agg(Polars.element.null_count)
# # =>
# # shape: (3,)
# # Series: 'a' [u32]
# # [
# # 1
# # 0
# # 2
# # ]
#
# @example
# s.list.agg(Polars.element.drop_nulls)
# # =>
# # shape: (3,)
# # Series: 'a' [list[i64]]
# # [
# # [1]
# # [42, 13]
# # []
# # ]
def agg(expr)
super
end
# Filter elements in each list by a boolean expression, returning a new Series of lists.
#
# @param predicate [Object]
# A boolean expression evaluated on each list element.
# Use `Polars.element` to refer to the current element.
#
# @return [Series]
#
# @example
# s = Polars::Series.new("a", [[1, 4], [8, 5], [3, 2]])
# s.list.filter(Polars.element % 2 == 0)
# # =>
# # shape: (3,)
# # Series: 'a' [list[i64]]
# # [
# # [4]
# # [8]
# # [2]
# # ]
def filter(predicate)
super
end
# Compute the SET UNION between the elements in this list and the elements of `other`.
#
# @param other [Object]
# Right hand side of the set operation.
#
# @return [Series]
#
# @example
# a = Polars::Series.new([[1, 2, 3], [], [nil, 3], [5, 6, 7]])
# b = Polars::Series.new([[2, 3, 4], [3], [3, 4, nil], [6, 8]])
# a.list.set_union(b)
# # =>
# # shape: (4,)
# # Series: '' [list[i64]]
# # [
# # [1, 2, … 4]
# # [3]
# # [null, 3, 4]
# # [5, 6, … 8]
# # ]
def set_union(other)
super
end
# Compute the SET DIFFERENCE between the elements in this list and the elements of `other`.
#
# @param other [Object]
# Right hand side of the set operation.
#
# @return [Series]
#
# @example
# a = Polars::Series.new([[1, 2, 3], [], [nil, 3], [5, 6, 7]])
# b = Polars::Series.new([[2, 3, 4], [3], [3, 4, nil], [6, 8]])
# a.list.set_difference(b)
# # =>
# # shape: (4,)
# # Series: '' [list[i64]]
# # [
# # [1]
# # []
# # []
# # [5, 7]
# # ]
def set_difference(other)
super
end
# Compute the SET INTERSECTION between the elements in this list and the elements of `other`.
#
# @param other [Object]
# Right hand side of the set operation.
#
# @return [Series]
#
# @example
# a = Polars::Series.new([[1, 2, 3], [], [nil, 3], [5, 6, 7]])
# b = Polars::Series.new([[2, 3, 4], [3], [3, 4, nil], [6, 8]])
# a.list.set_intersection(b)
# # =>
# # shape: (4,)
# # Series: '' [list[i64]]
# # [
# # [2, 3]
# # []
# # [null, 3]
# # [6]
# # ]
def set_intersection(other)
super
end
# Compute the SET SYMMETRIC DIFFERENCE between the elements in this list and the elements of `other`.
#
# @param other [Object]
# Right hand side of the set operation.
#
# @return [Series]
#
# @example
# a = Polars::Series.new([[1, 2, 3], [], [nil, 3], [5, 6, 7]])
# b = Polars::Series.new([[2, 3, 4], [3], [3, 4, nil], [6, 8]])
# a.list.set_symmetric_difference(b)
# # =>
# # shape: (4,)
# # Series: '' [list[i64]]
# # [
# # [1, 4]
# # [3]
# # [4]
# # [5, 7, 8]
# # ]
def set_symmetric_difference(other)
super
end
end
end