#[cfg(feature = "list_to_struct")]
use std::sync::RwLock;
use polars_core::prelude::*;
#[cfg(feature = "diff")]
use polars_core::series::ops::NullBehavior;
#[cfg(feature = "list_sets")]
use polars_core::utils::SuperTypeOptions;
use crate::prelude::function_expr::ListFunction;
use crate::prelude::*;
pub struct ListNameSpace(pub Expr);
impl ListNameSpace {
#[cfg(feature = "list_any_all")]
pub fn any(self) -> Expr {
self.0
.apply_private(FunctionExpr::ListExpr(ListFunction::Any))
.with_fmt("list.any")
}
#[cfg(feature = "list_any_all")]
pub fn all(self) -> Expr {
self.0
.apply_private(FunctionExpr::ListExpr(ListFunction::All))
.with_fmt("list.all")
}
#[cfg(feature = "list_drop_nulls")]
pub fn drop_nulls(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::DropNulls))
}
#[cfg(feature = "list_sample")]
pub fn sample_n(
self,
n: Expr,
with_replacement: bool,
shuffle: bool,
seed: Option<u64>,
) -> Expr {
self.0.map_many_private(
FunctionExpr::ListExpr(ListFunction::Sample {
is_fraction: false,
with_replacement,
shuffle,
seed,
}),
&[n],
false,
false,
)
}
#[cfg(feature = "list_sample")]
pub fn sample_fraction(
self,
fraction: Expr,
with_replacement: bool,
shuffle: bool,
seed: Option<u64>,
) -> Expr {
self.0.map_many_private(
FunctionExpr::ListExpr(ListFunction::Sample {
is_fraction: true,
with_replacement,
shuffle,
seed,
}),
&[fraction],
false,
false,
)
}
pub fn len(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Length))
}
pub fn max(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Max))
}
pub fn min(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Min))
}
pub fn sum(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Sum))
}
pub fn mean(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Mean))
}
pub fn median(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Median))
}
pub fn std(self, ddof: u8) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Std(ddof)))
}
pub fn var(self, ddof: u8) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Var(ddof)))
}
pub fn sort(self, options: SortOptions) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Sort(options)))
}
pub fn reverse(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Reverse))
}
pub fn unique(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Unique(false)))
}
pub fn unique_stable(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Unique(true)))
}
pub fn n_unique(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::NUnique))
}
pub fn get(self, index: Expr, null_on_oob: bool) -> Expr {
self.0.map_many_private(
FunctionExpr::ListExpr(ListFunction::Get(null_on_oob)),
&[index],
false,
false,
)
}
#[cfg(feature = "list_gather")]
pub fn gather(self, index: Expr, null_on_oob: bool) -> Expr {
self.0.map_many_private(
FunctionExpr::ListExpr(ListFunction::Gather(null_on_oob)),
&[index],
false,
false,
)
}
#[cfg(feature = "list_gather")]
pub fn gather_every(self, n: Expr, offset: Expr) -> Expr {
self.0.map_many_private(
FunctionExpr::ListExpr(ListFunction::GatherEvery),
&[n, offset],
false,
false,
)
}
pub fn first(self) -> Expr {
self.get(lit(0i64), true)
}
pub fn last(self) -> Expr {
self.get(lit(-1i64), true)
}
pub fn join(self, separator: Expr, ignore_nulls: bool) -> Expr {
self.0.map_many_private(
FunctionExpr::ListExpr(ListFunction::Join(ignore_nulls)),
&[separator],
false,
false,
)
}
pub fn arg_min(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::ArgMin))
}
pub fn arg_max(self) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::ArgMax))
}
#[cfg(feature = "diff")]
pub fn diff(self, n: i64, null_behavior: NullBehavior) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::Diff {
n,
null_behavior,
}))
}
pub fn shift(self, periods: Expr) -> Expr {
self.0.map_many_private(
FunctionExpr::ListExpr(ListFunction::Shift),
&[periods],
false,
false,
)
}
pub fn slice(self, offset: Expr, length: Expr) -> Expr {
self.0.map_many_private(
FunctionExpr::ListExpr(ListFunction::Slice),
&[offset, length],
false,
false,
)
}
pub fn head(self, n: Expr) -> Expr {
self.slice(lit(0), n)
}
pub fn tail(self, n: Expr) -> Expr {
self.slice(lit(0i64) - n.clone().cast(DataType::Int64), n)
}
#[cfg(feature = "dtype-array")]
pub fn to_array(self, width: usize) -> Expr {
self.0
.map_private(FunctionExpr::ListExpr(ListFunction::ToArray(width)))
}
#[cfg(feature = "list_to_struct")]
#[allow(clippy::wrong_self_convention)]
pub fn to_struct(
self,
n_fields: ListToStructWidthStrategy,
name_generator: Option<NameGenerator>,
upper_bound: usize,
) -> Expr {
let out_dtype = Arc::new(RwLock::new(None::<DataType>));
self.0
.map(
move |s| {
s.list()?
.to_struct(n_fields, name_generator.clone())
.map(|s| Some(s.into_series()))
},
GetOutput::map_dtype(move |dt: &DataType| {
let out = out_dtype.read().unwrap();
match out.as_ref() {
Some(dt) => Ok(dt.clone()),
None => {
drop(out);
let mut lock = out_dtype.write().unwrap();
let inner = dt.inner_dtype().unwrap();
let fields = (0..upper_bound)
.map(|i| {
let name = _default_struct_name_gen(i);
Field::from_owned(name, inner.clone())
})
.collect();
let dt = DataType::Struct(fields);
*lock = Some(dt.clone());
Ok(dt)
},
}
}),
)
.with_fmt("list.to_struct")
}
#[cfg(feature = "is_in")]
pub fn contains<E: Into<Expr>>(self, other: E) -> Expr {
let other = other.into();
self.0
.map_many_private(
FunctionExpr::ListExpr(ListFunction::Contains),
&[other],
false,
false,
)
.with_function_options(|mut options| {
options.input_wildcard_expansion = true;
options
})
}
#[cfg(feature = "list_count")]
pub fn count_matches<E: Into<Expr>>(self, element: E) -> Expr {
let other = element.into();
self.0
.map_many_private(
FunctionExpr::ListExpr(ListFunction::CountMatches),
&[other],
false,
false,
)
.with_function_options(|mut options| {
options.input_wildcard_expansion = true;
options
})
}
#[cfg(feature = "list_sets")]
fn set_operation(self, other: Expr, set_operation: SetOperation) -> Expr {
Expr::Function {
input: vec![self.0, other],
function: FunctionExpr::ListExpr(ListFunction::SetOperation(set_operation)),
options: FunctionOptions {
collect_groups: ApplyOptions::ElementWise,
returns_scalar: false,
cast_to_supertypes: Some(SuperTypeOptions { implode_list: true }),
input_wildcard_expansion: true,
..Default::default()
},
}
}
#[cfg(feature = "list_sets")]
pub fn union<E: Into<Expr>>(self, other: E) -> Expr {
let other = other.into();
self.set_operation(other, SetOperation::Union)
}
#[cfg(feature = "list_sets")]
pub fn set_difference<E: Into<Expr>>(self, other: E) -> Expr {
let other = other.into();
self.set_operation(other, SetOperation::Difference)
}
#[cfg(feature = "list_sets")]
pub fn set_intersection<E: Into<Expr>>(self, other: E) -> Expr {
let other = other.into();
self.set_operation(other, SetOperation::Intersection)
}
#[cfg(feature = "list_sets")]
pub fn set_symmetric_difference<E: Into<Expr>>(self, other: E) -> Expr {
let other = other.into();
self.set_operation(other, SetOperation::SymmetricDifference)
}
}