Path: blob/main/crates/polars-core/src/series/implementations/date.rs
6940 views
//! This module exists to reduce compilation times.1//!2//! All the data types are backed by a physical type in memory e.g. Date -> i32, Datetime-> i64.3//!4//! Series lead to code implementations of all traits. Whereas there are a lot of duplicates due to5//! data types being backed by the same physical type. In this module we reduce compile times by6//! opting for a little more run time cost. We cast to the physical type -> apply the operation and7//! (depending on the result) cast back to the original type8//!9use super::*;10#[cfg(feature = "algorithm_group_by")]11use crate::frame::group_by::*;12use crate::prelude::*;1314unsafe impl IntoSeries for DateChunked {15fn into_series(self) -> Series {16Series(Arc::new(SeriesWrap(self)))17}18}1920impl private::PrivateSeries for SeriesWrap<DateChunked> {21fn compute_len(&mut self) {22self.0.physical_mut().compute_len()23}2425fn _field(&self) -> Cow<'_, Field> {26Cow::Owned(self.0.field())27}2829fn _dtype(&self) -> &DataType {30self.0.dtype()31}3233fn _get_flags(&self) -> StatisticsFlags {34self.0.physical().get_flags()35}3637fn _set_flags(&mut self, flags: StatisticsFlags) {38self.0.physical_mut().set_flags(flags)39}4041#[cfg(feature = "zip_with")]42fn zip_with_same_type(&self, mask: &BooleanChunked, other: &Series) -> PolarsResult<Series> {43let other = other.to_physical_repr().into_owned();44self.045.physical()46.zip_with(mask, other.as_ref().as_ref())47.map(|ca| ca.into_date().into_series())48}4950fn into_total_eq_inner<'a>(&'a self) -> Box<dyn TotalEqInner + 'a> {51self.0.physical().into_total_eq_inner()52}5354fn into_total_ord_inner<'a>(&'a self) -> Box<dyn TotalOrdInner + 'a> {55self.0.physical().into_total_ord_inner()56}5758fn vec_hash(59&self,60random_state: PlSeedableRandomStateQuality,61buf: &mut Vec<u64>,62) -> PolarsResult<()> {63self.0.physical().vec_hash(random_state, buf)?;64Ok(())65}6667fn vec_hash_combine(68&self,69build_hasher: PlSeedableRandomStateQuality,70hashes: &mut [u64],71) -> PolarsResult<()> {72self.0.physical().vec_hash_combine(build_hasher, hashes)?;73Ok(())74}7576#[cfg(feature = "algorithm_group_by")]77unsafe fn agg_min(&self, groups: &GroupsType) -> Series {78self.0.physical().agg_min(groups).into_date().into_series()79}8081#[cfg(feature = "algorithm_group_by")]82unsafe fn agg_max(&self, groups: &GroupsType) -> Series {83self.0.physical().agg_max(groups).into_date().into_series()84}8586#[cfg(feature = "algorithm_group_by")]87unsafe fn agg_list(&self, groups: &GroupsType) -> Series {88// we cannot cast and dispatch as the inner type of the list would be incorrect89self.090.physical()91.agg_list(groups)92.cast(&DataType::List(Box::new(self.dtype().clone())))93.unwrap()94}9596fn subtract(&self, rhs: &Series) -> PolarsResult<Series> {97match rhs.dtype() {98DataType::Date => {99let dt = DataType::Datetime(TimeUnit::Microseconds, None);100let lhs = self.cast(&dt, CastOptions::NonStrict)?;101let rhs = rhs.cast(&dt)?;102lhs.subtract(&rhs)103},104DataType::Duration(_) => std::ops::Sub::sub(105&self.cast(106&DataType::Datetime(TimeUnit::Microseconds, None),107CastOptions::NonStrict,108)?,109rhs,110)?111.cast(&DataType::Date),112dtr => polars_bail!(opq = sub, DataType::Date, dtr),113}114}115116fn add_to(&self, rhs: &Series) -> PolarsResult<Series> {117match rhs.dtype() {118DataType::Duration(_) => std::ops::Add::add(119&self.cast(120&DataType::Datetime(TimeUnit::Microseconds, None),121CastOptions::NonStrict,122)?,123rhs,124)?125.cast(&DataType::Date),126dtr => polars_bail!(opq = add, DataType::Date, dtr),127}128}129130fn multiply(&self, rhs: &Series) -> PolarsResult<Series> {131polars_bail!(opq = mul, self.0.dtype(), rhs.dtype());132}133134fn divide(&self, rhs: &Series) -> PolarsResult<Series> {135polars_bail!(opq = div, self.0.dtype(), rhs.dtype());136}137138fn remainder(&self, rhs: &Series) -> PolarsResult<Series> {139polars_bail!(opq = rem, self.0.dtype(), rhs.dtype());140}141#[cfg(feature = "algorithm_group_by")]142fn group_tuples(&self, multithreaded: bool, sorted: bool) -> PolarsResult<GroupsType> {143self.0.physical().group_tuples(multithreaded, sorted)144}145146fn arg_sort_multiple(147&self,148by: &[Column],149options: &SortMultipleOptions,150) -> PolarsResult<IdxCa> {151self.0.physical().arg_sort_multiple(by, options)152}153}154155impl SeriesTrait for SeriesWrap<DateChunked> {156fn rename(&mut self, name: PlSmallStr) {157self.0.rename(name);158}159160fn chunk_lengths(&self) -> ChunkLenIter<'_> {161self.0.physical().chunk_lengths()162}163164fn name(&self) -> &PlSmallStr {165self.0.name()166}167168fn chunks(&self) -> &Vec<ArrayRef> {169self.0.physical().chunks()170}171172unsafe fn chunks_mut(&mut self) -> &mut Vec<ArrayRef> {173self.0.physical_mut().chunks_mut()174}175176fn shrink_to_fit(&mut self) {177self.0.physical_mut().shrink_to_fit()178}179180fn slice(&self, offset: i64, length: usize) -> Series {181self.0.slice(offset, length).into_series()182}183184fn split_at(&self, offset: i64) -> (Series, Series) {185let (a, b) = self.0.split_at(offset);186(a.into_series(), b.into_series())187}188189fn _sum_as_f64(&self) -> f64 {190self.0.physical()._sum_as_f64()191}192193fn mean(&self) -> Option<f64> {194self.0.physical().mean()195}196197fn median(&self) -> Option<f64> {198self.0.physical().median()199}200201fn append(&mut self, other: &Series) -> PolarsResult<()> {202polars_ensure!(self.0.dtype() == other.dtype(), append);203let mut other = other.to_physical_repr().into_owned();204self.0205.physical_mut()206.append_owned(std::mem::take(other._get_inner_mut().as_mut()))207}208209fn append_owned(&mut self, mut other: Series) -> PolarsResult<()> {210polars_ensure!(self.0.dtype() == other.dtype(), append);211self.0.physical_mut().append_owned(std::mem::take(212&mut other213._get_inner_mut()214.as_any_mut()215.downcast_mut::<DateChunked>()216.unwrap()217.phys,218))219}220221fn extend(&mut self, other: &Series) -> PolarsResult<()> {222polars_ensure!(self.0.dtype() == other.dtype(), extend);223// 3 refs224// ref Cow225// ref SeriesTrait226// ref ChunkedArray227let other = other.to_physical_repr();228self.0229.physical_mut()230.extend(other.as_ref().as_ref().as_ref())?;231Ok(())232}233234fn filter(&self, filter: &BooleanChunked) -> PolarsResult<Series> {235self.0236.physical()237.filter(filter)238.map(|ca| ca.into_date().into_series())239}240241fn take(&self, indices: &IdxCa) -> PolarsResult<Series> {242Ok(self.0.physical().take(indices)?.into_date().into_series())243}244245unsafe fn take_unchecked(&self, indices: &IdxCa) -> Series {246self.0247.physical()248.take_unchecked(indices)249.into_date()250.into_series()251}252253fn take_slice(&self, indices: &[IdxSize]) -> PolarsResult<Series> {254Ok(self.0.physical().take(indices)?.into_date().into_series())255}256257unsafe fn take_slice_unchecked(&self, indices: &[IdxSize]) -> Series {258self.0259.physical()260.take_unchecked(indices)261.into_date()262.into_series()263}264265fn len(&self) -> usize {266self.0.len()267}268269fn rechunk(&self) -> Series {270self.0271.physical()272.rechunk()273.into_owned()274.into_date()275.into_series()276}277278fn new_from_index(&self, index: usize, length: usize) -> Series {279self.0280.physical()281.new_from_index(index, length)282.into_date()283.into_series()284}285286fn cast(&self, dtype: &DataType, cast_options: CastOptions) -> PolarsResult<Series> {287match dtype {288DataType::String => Ok(self289.0290.clone()291.into_series()292.date()293.unwrap()294.to_string("%Y-%m-%d")?295.into_series()),296#[cfg(feature = "dtype-datetime")]297DataType::Datetime(_, _) => {298let mut out = self.0.cast_with_options(dtype, CastOptions::NonStrict)?;299out.set_sorted_flag(self.0.physical().is_sorted_flag());300Ok(out)301},302_ => self.0.cast_with_options(dtype, cast_options),303}304}305306#[inline]307unsafe fn get_unchecked(&self, index: usize) -> AnyValue<'_> {308self.0.get_any_value_unchecked(index)309}310311fn sort_with(&self, options: SortOptions) -> PolarsResult<Series> {312Ok(self313.0314.physical()315.sort_with(options)316.into_date()317.into_series())318}319320fn arg_sort(&self, options: SortOptions) -> IdxCa {321self.0.physical().arg_sort(options)322}323324fn null_count(&self) -> usize {325self.0.null_count()326}327328fn has_nulls(&self) -> bool {329self.0.has_nulls()330}331332#[cfg(feature = "algorithm_group_by")]333fn unique(&self) -> PolarsResult<Series> {334self.0335.physical()336.unique()337.map(|ca| ca.into_date().into_series())338}339340#[cfg(feature = "algorithm_group_by")]341fn n_unique(&self) -> PolarsResult<usize> {342self.0.physical().n_unique()343}344345#[cfg(feature = "algorithm_group_by")]346fn arg_unique(&self) -> PolarsResult<IdxCa> {347self.0.physical().arg_unique()348}349350fn is_null(&self) -> BooleanChunked {351self.0.is_null()352}353354fn is_not_null(&self) -> BooleanChunked {355self.0.is_not_null()356}357358fn reverse(&self) -> Series {359self.0.physical().reverse().into_date().into_series()360}361362fn as_single_ptr(&mut self) -> PolarsResult<usize> {363self.0.physical_mut().as_single_ptr()364}365366fn shift(&self, periods: i64) -> Series {367self.0.physical().shift(periods).into_date().into_series()368}369370fn max_reduce(&self) -> PolarsResult<Scalar> {371let sc = self.0.physical().max_reduce();372let av = sc.value().cast(self.dtype()).into_static();373Ok(Scalar::new(self.dtype().clone(), av))374}375376fn min_reduce(&self) -> PolarsResult<Scalar> {377let sc = self.0.physical().min_reduce();378let av = sc.value().cast(self.dtype()).into_static();379Ok(Scalar::new(self.dtype().clone(), av))380}381382fn median_reduce(&self) -> PolarsResult<Scalar> {383let av: AnyValue = self384.median()385.map(|v| (v * (US_IN_DAY as f64)) as i64)386.into();387Ok(Scalar::new(388DataType::Datetime(TimeUnit::Microseconds, None),389av,390))391}392393fn clone_inner(&self) -> Arc<dyn SeriesTrait> {394Arc::new(SeriesWrap(Clone::clone(&self.0)))395}396397fn find_validity_mismatch(&self, other: &Series, idxs: &mut Vec<IdxSize>) {398self.0.physical().find_validity_mismatch(other, idxs)399}400401fn as_any(&self) -> &dyn Any {402&self.0403}404405fn as_any_mut(&mut self) -> &mut dyn Any {406&mut self.0407}408409fn as_phys_any(&self) -> &dyn Any {410self.0.physical()411}412413fn as_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {414self as _415}416}417418impl private::PrivateSeriesNumeric for SeriesWrap<DateChunked> {419fn bit_repr(&self) -> Option<BitRepr> {420Some(self.0.physical().to_bit_repr())421}422}423424425