Path: blob/main/crates/polars-core/src/series/implementations/mod.rs
6940 views
#![allow(unsafe_op_in_unsafe_fn)]1#[cfg(feature = "dtype-array")]2mod array;3mod binary;4mod binary_offset;5mod boolean;6#[cfg(feature = "dtype-categorical")]7mod categorical;8#[cfg(feature = "dtype-date")]9mod date;10#[cfg(feature = "dtype-datetime")]11mod datetime;12#[cfg(feature = "dtype-decimal")]13mod decimal;14#[cfg(feature = "dtype-duration")]15mod duration;16mod floats;17mod list;18pub(crate) mod null;19#[cfg(feature = "object")]20mod object;21mod string;22#[cfg(feature = "dtype-struct")]23mod struct_;24#[cfg(feature = "dtype-time")]25mod time;2627use std::any::Any;28use std::borrow::Cow;2930use polars_compute::rolling::QuantileMethod;31use polars_utils::aliases::PlSeedableRandomStateQuality;3233use super::*;34use crate::chunked_array::AsSinglePtr;35use crate::chunked_array::comparison::*;36use crate::chunked_array::ops::compare_inner::{37IntoTotalEqInner, IntoTotalOrdInner, TotalEqInner, TotalOrdInner,38};3940// Utility wrapper struct41pub(crate) struct SeriesWrap<T>(pub T);4243impl<T: PolarsDataType> From<ChunkedArray<T>> for SeriesWrap<ChunkedArray<T>> {44fn from(ca: ChunkedArray<T>) -> Self {45SeriesWrap(ca)46}47}4849impl<T: PolarsDataType> Deref for SeriesWrap<ChunkedArray<T>> {50type Target = ChunkedArray<T>;5152fn deref(&self) -> &Self::Target {53&self.054}55}5657unsafe impl<T: PolarsPhysicalType> IntoSeries for ChunkedArray<T> {58fn into_series(self) -> Series {59T::ca_into_series(self)60}61}6263macro_rules! impl_dyn_series {64($ca: ident, $pdt:ty) => {65impl private::PrivateSeries for SeriesWrap<$ca> {66fn compute_len(&mut self) {67self.0.compute_len()68}6970fn _field(&self) -> Cow<'_, Field> {71Cow::Borrowed(self.0.ref_field())72}7374fn _dtype(&self) -> &DataType {75self.0.ref_field().dtype()76}7778fn _get_flags(&self) -> StatisticsFlags {79self.0.get_flags()80}8182fn _set_flags(&mut self, flags: StatisticsFlags) {83self.0.set_flags(flags)84}8586unsafe fn equal_element(87&self,88idx_self: usize,89idx_other: usize,90other: &Series,91) -> bool {92self.0.equal_element(idx_self, idx_other, other)93}9495#[cfg(feature = "zip_with")]96fn zip_with_same_type(97&self,98mask: &BooleanChunked,99other: &Series,100) -> PolarsResult<Series> {101ChunkZip::zip_with(&self.0, mask, other.as_ref().as_ref())102.map(|ca| ca.into_series())103}104fn into_total_eq_inner<'a>(&'a self) -> Box<dyn TotalEqInner + 'a> {105(&self.0).into_total_eq_inner()106}107fn into_total_ord_inner<'a>(&'a self) -> Box<dyn TotalOrdInner + 'a> {108(&self.0).into_total_ord_inner()109}110111fn vec_hash(112&self,113random_state: PlSeedableRandomStateQuality,114buf: &mut Vec<u64>,115) -> PolarsResult<()> {116self.0.vec_hash(random_state, buf)?;117Ok(())118}119120fn vec_hash_combine(121&self,122build_hasher: PlSeedableRandomStateQuality,123hashes: &mut [u64],124) -> PolarsResult<()> {125self.0.vec_hash_combine(build_hasher, hashes)?;126Ok(())127}128129#[cfg(feature = "algorithm_group_by")]130unsafe fn agg_min(&self, groups: &GroupsType) -> Series {131self.0.agg_min(groups)132}133134#[cfg(feature = "algorithm_group_by")]135unsafe fn agg_max(&self, groups: &GroupsType) -> Series {136self.0.agg_max(groups)137}138139#[cfg(feature = "algorithm_group_by")]140unsafe fn agg_sum(&self, groups: &GroupsType) -> Series {141use DataType::*;142match self.dtype() {143Int8 | UInt8 | Int16 | UInt16 => self144.cast(&Int64, CastOptions::Overflowing)145.unwrap()146.agg_sum(groups),147_ => self.0.agg_sum(groups),148}149}150151#[cfg(feature = "algorithm_group_by")]152unsafe fn agg_std(&self, groups: &GroupsType, ddof: u8) -> Series {153self.0.agg_std(groups, ddof)154}155156#[cfg(feature = "algorithm_group_by")]157unsafe fn agg_var(&self, groups: &GroupsType, ddof: u8) -> Series {158self.0.agg_var(groups, ddof)159}160161#[cfg(feature = "algorithm_group_by")]162unsafe fn agg_list(&self, groups: &GroupsType) -> Series {163self.0.agg_list(groups)164}165166#[cfg(feature = "bitwise")]167unsafe fn agg_and(&self, groups: &GroupsType) -> Series {168self.0.agg_and(groups)169}170#[cfg(feature = "bitwise")]171unsafe fn agg_or(&self, groups: &GroupsType) -> Series {172self.0.agg_or(groups)173}174#[cfg(feature = "bitwise")]175unsafe fn agg_xor(&self, groups: &GroupsType) -> Series {176self.0.agg_xor(groups)177}178179fn subtract(&self, rhs: &Series) -> PolarsResult<Series> {180NumOpsDispatch::subtract(&self.0, rhs)181}182fn add_to(&self, rhs: &Series) -> PolarsResult<Series> {183NumOpsDispatch::add_to(&self.0, rhs)184}185fn multiply(&self, rhs: &Series) -> PolarsResult<Series> {186NumOpsDispatch::multiply(&self.0, rhs)187}188fn divide(&self, rhs: &Series) -> PolarsResult<Series> {189NumOpsDispatch::divide(&self.0, rhs)190}191fn remainder(&self, rhs: &Series) -> PolarsResult<Series> {192NumOpsDispatch::remainder(&self.0, rhs)193}194#[cfg(feature = "algorithm_group_by")]195fn group_tuples(&self, multithreaded: bool, sorted: bool) -> PolarsResult<GroupsType> {196IntoGroupsType::group_tuples(&self.0, multithreaded, sorted)197}198199fn arg_sort_multiple(200&self,201by: &[Column],202options: &SortMultipleOptions,203) -> PolarsResult<IdxCa> {204self.0.arg_sort_multiple(by, options)205}206}207208impl SeriesTrait for SeriesWrap<$ca> {209#[cfg(feature = "rolling_window")]210fn rolling_map(211&self,212_f: &dyn Fn(&Series) -> PolarsResult<Series>,213_options: RollingOptionsFixedWindow,214) -> PolarsResult<Series> {215ChunkRollApply::rolling_map(&self.0, _f, _options).map(|ca| ca.into_series())216}217218fn rename(&mut self, name: PlSmallStr) {219self.0.rename(name);220}221222fn chunk_lengths(&self) -> ChunkLenIter<'_> {223self.0.chunk_lengths()224}225fn name(&self) -> &PlSmallStr {226self.0.name()227}228229fn chunks(&self) -> &Vec<ArrayRef> {230self.0.chunks()231}232unsafe fn chunks_mut(&mut self) -> &mut Vec<ArrayRef> {233self.0.chunks_mut()234}235fn shrink_to_fit(&mut self) {236self.0.shrink_to_fit()237}238239fn slice(&self, offset: i64, length: usize) -> Series {240self.0.slice(offset, length).into_series()241}242243fn split_at(&self, offset: i64) -> (Series, Series) {244let (a, b) = self.0.split_at(offset);245(a.into_series(), b.into_series())246}247248fn append(&mut self, other: &Series) -> PolarsResult<()> {249polars_ensure!(self.0.dtype() == other.dtype(), append);250self.0.append(other.as_ref().as_ref())?;251Ok(())252}253fn append_owned(&mut self, other: Series) -> PolarsResult<()> {254polars_ensure!(self.0.dtype() == other.dtype(), append);255self.0.append_owned(other.take_inner())256}257258fn extend(&mut self, other: &Series) -> PolarsResult<()> {259polars_ensure!(self.0.dtype() == other.dtype(), extend);260self.0.extend(other.as_ref().as_ref())?;261Ok(())262}263264fn filter(&self, filter: &BooleanChunked) -> PolarsResult<Series> {265ChunkFilter::filter(&self.0, filter).map(|ca| ca.into_series())266}267268fn _sum_as_f64(&self) -> f64 {269self.0._sum_as_f64()270}271272fn mean(&self) -> Option<f64> {273self.0.mean()274}275276fn median(&self) -> Option<f64> {277self.0.median()278}279280fn std(&self, ddof: u8) -> Option<f64> {281self.0.std(ddof)282}283284fn var(&self, ddof: u8) -> Option<f64> {285self.0.var(ddof)286}287288fn take(&self, indices: &IdxCa) -> PolarsResult<Series> {289Ok(self.0.take(indices)?.into_series())290}291292unsafe fn take_unchecked(&self, indices: &IdxCa) -> Series {293self.0.take_unchecked(indices).into_series()294}295296fn take_slice(&self, indices: &[IdxSize]) -> PolarsResult<Series> {297Ok(self.0.take(indices)?.into_series())298}299300unsafe fn take_slice_unchecked(&self, indices: &[IdxSize]) -> Series {301self.0.take_unchecked(indices).into_series()302}303304fn len(&self) -> usize {305self.0.len()306}307308fn rechunk(&self) -> Series {309self.0.rechunk().into_owned().into_series()310}311312fn new_from_index(&self, index: usize, length: usize) -> Series {313ChunkExpandAtIndex::new_from_index(&self.0, index, length).into_series()314}315316fn cast(&self, dtype: &DataType, options: CastOptions) -> PolarsResult<Series> {317self.0.cast_with_options(dtype, options)318}319320#[inline]321unsafe fn get_unchecked(&self, index: usize) -> AnyValue<'_> {322self.0.get_any_value_unchecked(index)323}324325fn sort_with(&self, options: SortOptions) -> PolarsResult<Series> {326Ok(ChunkSort::sort_with(&self.0, options).into_series())327}328329fn arg_sort(&self, options: SortOptions) -> IdxCa {330ChunkSort::arg_sort(&self.0, options)331}332333fn null_count(&self) -> usize {334self.0.null_count()335}336337fn has_nulls(&self) -> bool {338self.0.has_nulls()339}340341#[cfg(feature = "algorithm_group_by")]342fn unique(&self) -> PolarsResult<Series> {343ChunkUnique::unique(&self.0).map(|ca| ca.into_series())344}345346#[cfg(feature = "algorithm_group_by")]347fn n_unique(&self) -> PolarsResult<usize> {348ChunkUnique::n_unique(&self.0)349}350351#[cfg(feature = "algorithm_group_by")]352fn arg_unique(&self) -> PolarsResult<IdxCa> {353ChunkUnique::arg_unique(&self.0)354}355356fn is_null(&self) -> BooleanChunked {357self.0.is_null()358}359360fn is_not_null(&self) -> BooleanChunked {361self.0.is_not_null()362}363364fn reverse(&self) -> Series {365ChunkReverse::reverse(&self.0).into_series()366}367368fn as_single_ptr(&mut self) -> PolarsResult<usize> {369self.0.as_single_ptr()370}371372fn shift(&self, periods: i64) -> Series {373ChunkShift::shift(&self.0, periods).into_series()374}375376fn sum_reduce(&self) -> PolarsResult<Scalar> {377Ok(ChunkAggSeries::sum_reduce(&self.0))378}379fn max_reduce(&self) -> PolarsResult<Scalar> {380Ok(ChunkAggSeries::max_reduce(&self.0))381}382fn min_reduce(&self) -> PolarsResult<Scalar> {383Ok(ChunkAggSeries::min_reduce(&self.0))384}385fn median_reduce(&self) -> PolarsResult<Scalar> {386Ok(QuantileAggSeries::median_reduce(&self.0))387}388fn var_reduce(&self, ddof: u8) -> PolarsResult<Scalar> {389Ok(VarAggSeries::var_reduce(&self.0, ddof))390}391fn std_reduce(&self, ddof: u8) -> PolarsResult<Scalar> {392Ok(VarAggSeries::std_reduce(&self.0, ddof))393}394fn quantile_reduce(395&self,396quantile: f64,397method: QuantileMethod,398) -> PolarsResult<Scalar> {399QuantileAggSeries::quantile_reduce(&self.0, quantile, method)400}401402#[cfg(feature = "bitwise")]403fn and_reduce(&self) -> PolarsResult<Scalar> {404let dt = <$pdt as PolarsDataType>::get_static_dtype();405let av = self.0.and_reduce().map_or(AnyValue::Null, Into::into);406407Ok(Scalar::new(dt, av))408}409410#[cfg(feature = "bitwise")]411fn or_reduce(&self) -> PolarsResult<Scalar> {412let dt = <$pdt as PolarsDataType>::get_static_dtype();413let av = self.0.or_reduce().map_or(AnyValue::Null, Into::into);414415Ok(Scalar::new(dt, av))416}417418#[cfg(feature = "bitwise")]419fn xor_reduce(&self) -> PolarsResult<Scalar> {420let dt = <$pdt as PolarsDataType>::get_static_dtype();421let av = self.0.xor_reduce().map_or(AnyValue::Null, Into::into);422423Ok(Scalar::new(dt, av))424}425426#[cfg(feature = "approx_unique")]427fn approx_n_unique(&self) -> PolarsResult<IdxSize> {428Ok(ChunkApproxNUnique::approx_n_unique(&self.0))429}430431fn clone_inner(&self) -> Arc<dyn SeriesTrait> {432Arc::new(SeriesWrap(Clone::clone(&self.0)))433}434435fn find_validity_mismatch(&self, other: &Series, idxs: &mut Vec<IdxSize>) {436self.0.find_validity_mismatch(other, idxs)437}438439#[cfg(feature = "checked_arithmetic")]440fn checked_div(&self, rhs: &Series) -> PolarsResult<Series> {441self.0.checked_div(rhs)442}443444fn as_any(&self) -> &dyn Any {445&self.0446}447448fn as_any_mut(&mut self) -> &mut dyn Any {449&mut self.0450}451452fn as_phys_any(&self) -> &dyn Any {453&self.0454}455456fn as_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {457self as _458}459}460};461}462463#[cfg(feature = "dtype-u8")]464impl_dyn_series!(UInt8Chunked, UInt8Type);465#[cfg(feature = "dtype-u16")]466impl_dyn_series!(UInt16Chunked, UInt16Type);467impl_dyn_series!(UInt32Chunked, UInt32Type);468impl_dyn_series!(UInt64Chunked, UInt64Type);469#[cfg(feature = "dtype-i8")]470impl_dyn_series!(Int8Chunked, Int8Type);471#[cfg(feature = "dtype-i16")]472impl_dyn_series!(Int16Chunked, Int16Type);473impl_dyn_series!(Int32Chunked, Int32Type);474impl_dyn_series!(Int64Chunked, Int64Type);475#[cfg(feature = "dtype-i128")]476impl_dyn_series!(Int128Chunked, Int128Type);477478impl<T: PolarsNumericType> private::PrivateSeriesNumeric for SeriesWrap<ChunkedArray<T>> {479fn bit_repr(&self) -> Option<BitRepr> {480Some(self.0.to_bit_repr())481}482}483484impl private::PrivateSeriesNumeric for SeriesWrap<StringChunked> {485fn bit_repr(&self) -> Option<BitRepr> {486None487}488}489impl private::PrivateSeriesNumeric for SeriesWrap<BinaryChunked> {490fn bit_repr(&self) -> Option<BitRepr> {491None492}493}494impl private::PrivateSeriesNumeric for SeriesWrap<BinaryOffsetChunked> {495fn bit_repr(&self) -> Option<BitRepr> {496None497}498}499impl private::PrivateSeriesNumeric for SeriesWrap<ListChunked> {500fn bit_repr(&self) -> Option<BitRepr> {501None502}503}504#[cfg(feature = "dtype-array")]505impl private::PrivateSeriesNumeric for SeriesWrap<ArrayChunked> {506fn bit_repr(&self) -> Option<BitRepr> {507None508}509}510impl private::PrivateSeriesNumeric for SeriesWrap<BooleanChunked> {511fn bit_repr(&self) -> Option<BitRepr> {512let repr = self513.0514.cast_with_options(&DataType::UInt32, CastOptions::NonStrict)515.unwrap()516.u32()517.unwrap()518.clone();519520Some(BitRepr::U32(repr))521}522}523524525