Path: blob/main/crates/polars-python/src/series/aggregation.rs
7889 views
use DataType::*;1use polars::prelude::*;2use pyo3::prelude::*;34use super::PySeries;5use crate::conversion::Wrap;6use crate::utils::EnterPolarsExt;78fn scalar_to_py(scalar: PyResult<Scalar>, py: Python<'_>) -> PyResult<Bound<'_, PyAny>> {9Wrap(scalar?.as_any_value()).into_pyobject(py)10}1112#[pymethods]13impl PySeries {14fn any(&self, py: Python<'_>, ignore_nulls: bool) -> PyResult<Option<bool>> {15py.enter_polars(|| {16let s = self.series.read();17let s = s.bool()?;18PolarsResult::Ok(if ignore_nulls {19Some(s.any())20} else {21s.any_kleene()22})23})24}2526fn all(&self, py: Python<'_>, ignore_nulls: bool) -> PyResult<Option<bool>> {27py.enter_polars(|| {28let s = self.series.read();29let s = s.bool()?;30PolarsResult::Ok(if ignore_nulls {31Some(s.all())32} else {33s.all_kleene()34})35})36}3738fn arg_max(&self, py: Python) -> PyResult<Option<usize>> {39py.enter_polars_ok(|| self.series.read().arg_max())40}4142fn arg_min(&self, py: Python) -> PyResult<Option<usize>> {43py.enter_polars_ok(|| self.series.read().arg_min())44}4546fn min<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {47scalar_to_py(py.enter_polars(|| self.series.read().min_reduce()), py)48}4950fn max<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {51scalar_to_py(py.enter_polars(|| self.series.read().max_reduce()), py)52}5354fn mean<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {55let s = self.series.read();56match s.dtype() {57Boolean => scalar_to_py(58py.enter_polars(|| s.cast(&DataType::UInt8).unwrap().mean_reduce()),59py,60),61// For non-numeric output types we require mean_reduce.62dt if dt.is_temporal() => scalar_to_py(py.enter_polars(|| s.mean_reduce()), py),63_ => Ok(s.mean().into_pyobject(py)?),64}65}6667fn median<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {68let s = self.series.read();69match s.dtype() {70Boolean => scalar_to_py(71py.enter_polars(|| s.cast(&DataType::UInt8).unwrap().median_reduce()),72py,73),74// For non-numeric output types we require median_reduce.75dt if dt.is_temporal() => scalar_to_py(py.enter_polars(|| s.median_reduce()), py),76_ => Ok(s.median().into_pyobject(py)?),77}78}7980fn product<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {81scalar_to_py(py.enter_polars(|| self.series.read().product()), py)82}8384fn quantile<'py>(85&self,86py: Python<'py>,87quantile: f64,88interpolation: Wrap<QuantileMethod>,89) -> PyResult<Bound<'py, PyAny>> {90scalar_to_py(91py.enter_polars(|| {92self.series93.read()94.quantile_reduce(quantile, interpolation.0)95}),96py,97)98}99100fn std<'py>(&self, py: Python<'py>, ddof: u8) -> PyResult<Bound<'py, PyAny>> {101scalar_to_py(py.enter_polars(|| self.series.read().std_reduce(ddof)), py)102}103104fn var<'py>(&self, py: Python<'py>, ddof: u8) -> PyResult<Bound<'py, PyAny>> {105scalar_to_py(py.enter_polars(|| self.series.read().var_reduce(ddof)), py)106}107108fn sum<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {109scalar_to_py(py.enter_polars(|| self.series.read().sum_reduce()), py)110}111112fn first<'py>(&self, py: Python<'py>, ignore_nulls: bool) -> PyResult<Bound<'py, PyAny>> {113let result = if ignore_nulls {114py.enter_polars_ok(|| self.series.read().first_non_null())115} else {116py.enter_polars_ok(|| self.series.read().first())117};118scalar_to_py(result, py)119}120121fn last<'py>(&self, py: Python<'py>, ignore_nulls: bool) -> PyResult<Bound<'py, PyAny>> {122let result = if ignore_nulls {123py.enter_polars_ok(|| self.series.read().last_non_null())124} else {125py.enter_polars_ok(|| self.series.read().last())126};127scalar_to_py(result, py)128}129130#[cfg(feature = "approx_unique")]131fn approx_n_unique(&self, py: Python) -> PyResult<IdxSize> {132py.enter_polars(|| self.series.read().approx_n_unique())133}134135#[cfg(feature = "bitwise")]136fn bitwise_and<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {137scalar_to_py(py.enter_polars(|| self.series.read().and_reduce()), py)138}139140#[cfg(feature = "bitwise")]141fn bitwise_or<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {142scalar_to_py(py.enter_polars(|| self.series.read().or_reduce()), py)143}144145#[cfg(feature = "bitwise")]146fn bitwise_xor<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {147scalar_to_py(py.enter_polars(|| self.series.read().xor_reduce()), py)148}149}150151152