Path: blob/main/crates/polars-ops/src/series/ops/arg_min_max.rs
8475 views
use polars_core::chunked_array::arg_min_max::{1arg_max_binary, arg_max_bool, arg_max_numeric, arg_max_str, arg_min_binary, arg_min_bool,2arg_min_numeric, arg_min_str,3};4#[cfg(feature = "dtype-categorical")]5use polars_core::chunked_array::arg_min_max::{arg_max_cat, arg_min_cat};6#[cfg(feature = "dtype-categorical")]7use polars_core::with_match_categorical_physical_type;89use super::*;1011/// Argmin/ Argmax12pub trait ArgAgg {13/// Get the index of the minimal value14fn arg_min(&self) -> Option<usize>;15/// Get the index of the maximal value16fn arg_max(&self) -> Option<usize>;17}1819macro_rules! with_match_physical_numeric_polars_type {(20$key_type:expr, | $_:tt $T:ident | $($body:tt)*21) => ({22macro_rules! __with_ty__ {( $_ $T:ident ) => ( $($body)* )}23use DataType::*;24match $key_type {25#[cfg(feature = "dtype-i8")]26Int8 => __with_ty__! { Int8Type },27#[cfg(feature = "dtype-i16")]28Int16 => __with_ty__! { Int16Type },29Int32 => __with_ty__! { Int32Type },30Int64 => __with_ty__! { Int64Type },31#[cfg(feature = "dtype-i128")]32Int128 => __with_ty__! { Int128Type },33#[cfg(feature = "dtype-u8")]34UInt8 => __with_ty__! { UInt8Type },35#[cfg(feature = "dtype-u16")]36UInt16 => __with_ty__! { UInt16Type },37UInt32 => __with_ty__! { UInt32Type },38UInt64 => __with_ty__! { UInt64Type },39#[cfg(feature = "dtype-u128")]40UInt128 => __with_ty__! { UInt128Type },41#[cfg(feature = "dtype-f16")]42Float16 => __with_ty__! { Float16Type },43Float32 => __with_ty__! { Float32Type },44Float64 => __with_ty__! { Float64Type },45dt => panic!("not implemented for dtype {:?}", dt),46}47})}4849impl ArgAgg for Series {50fn arg_min(&self) -> Option<usize> {51use DataType::*;52let phys_s = self.to_physical_repr();53match self.dtype() {54#[cfg(feature = "dtype-categorical")]55Categorical(cats, _) => {56with_match_categorical_physical_type!(cats.physical(), |$C| {57arg_min_cat(self.cat::<$C>().unwrap())58})59},60#[cfg(feature = "dtype-categorical")]61Enum(_, _) => phys_s.arg_min(),62#[cfg(feature = "dtype-decimal")]63Decimal(_, _) => phys_s.arg_min(),64Date | Datetime(_, _) | Duration(_) | Time => phys_s.arg_min(),65String => arg_min_str(self.str().unwrap()),66Binary => arg_min_binary(self.binary().unwrap()),67Boolean => arg_min_bool(self.bool().unwrap()),68dt if dt.is_primitive_numeric() => {69with_match_physical_numeric_polars_type!(phys_s.dtype(), |$T| {70let ca: &ChunkedArray<$T> = phys_s.as_ref().as_ref().as_ref();71arg_min_numeric(ca)72})73},74_ => None,75}76}7778fn arg_max(&self) -> Option<usize> {79use DataType::*;80let phys_s = self.to_physical_repr();81match self.dtype() {82#[cfg(feature = "dtype-categorical")]83Categorical(cats, _) => {84with_match_categorical_physical_type!(cats.physical(), |$C| {85arg_max_cat(self.cat::<$C>().unwrap())86})87},88#[cfg(feature = "dtype-categorical")]89Enum(_, _) => phys_s.arg_max(),90#[cfg(feature = "dtype-decimal")]91Decimal(_, _) => phys_s.arg_max(),92Date | Datetime(_, _) | Duration(_) | Time => phys_s.arg_max(),93String => arg_max_str(self.str().unwrap()),94Binary => arg_max_binary(self.binary().unwrap()),95Boolean => arg_max_bool(self.bool().unwrap()),96dt if dt.is_primitive_numeric() => {97with_match_physical_numeric_polars_type!(phys_s.dtype(), |$T| {98let ca: &ChunkedArray<$T> = phys_s.as_ref().as_ref().as_ref();99arg_max_numeric(ca)100})101},102_ => None,103}104}105}106107108