Path: blob/main/crates/polars-core/src/series/implementations/time.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 TimeChunked {15fn into_series(self) -> Series {16Series(Arc::new(SeriesWrap(self)))17}18}1920impl private::PrivateSeries for SeriesWrap<TimeChunked> {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_time().into_series())48}4950fn into_total_eq_inner<'a>(&'a self) -> Box<dyn TotalEqInner + 'a> {51self.0.physical().into_total_eq_inner()52}53fn into_total_ord_inner<'a>(&'a self) -> Box<dyn TotalOrdInner + 'a> {54self.0.physical().into_total_ord_inner()55}5657fn vec_hash(58&self,59random_state: PlSeedableRandomStateQuality,60buf: &mut Vec<u64>,61) -> PolarsResult<()> {62self.0.physical().vec_hash(random_state, buf)?;63Ok(())64}6566fn vec_hash_combine(67&self,68build_hasher: PlSeedableRandomStateQuality,69hashes: &mut [u64],70) -> PolarsResult<()> {71self.0.physical().vec_hash_combine(build_hasher, hashes)?;72Ok(())73}7475#[cfg(feature = "algorithm_group_by")]76unsafe fn agg_min(&self, groups: &GroupsType) -> Series {77self.0.physical().agg_min(groups).into_time().into_series()78}7980#[cfg(feature = "algorithm_group_by")]81unsafe fn agg_max(&self, groups: &GroupsType) -> Series {82self.0.physical().agg_max(groups).into_time().into_series()83}8485#[cfg(feature = "algorithm_group_by")]86unsafe fn agg_list(&self, groups: &GroupsType) -> Series {87// we cannot cast and dispatch as the inner type of the list would be incorrect88self.089.physical()90.agg_list(groups)91.cast(&DataType::List(Box::new(self.dtype().clone())))92.unwrap()93}9495fn subtract(&self, rhs: &Series) -> PolarsResult<Series> {96let rhs = rhs.time().map_err(|_| polars_err!(InvalidOperation: "cannot subtract a {} dtype with a series of type: {}", self.dtype(), rhs.dtype()))?;9798let phys = self99.0100.physical()101.subtract(&rhs.physical().clone().into_series())?;102103Ok(phys.into_duration(TimeUnit::Nanoseconds))104}105106fn add_to(&self, rhs: &Series) -> PolarsResult<Series> {107polars_bail!(opq = add, DataType::Time, rhs.dtype());108}109110fn multiply(&self, rhs: &Series) -> PolarsResult<Series> {111polars_bail!(opq = mul, self.0.dtype(), rhs.dtype());112}113114fn divide(&self, rhs: &Series) -> PolarsResult<Series> {115polars_bail!(opq = div, self.0.dtype(), rhs.dtype());116}117118fn remainder(&self, rhs: &Series) -> PolarsResult<Series> {119polars_bail!(opq = rem, self.0.dtype(), rhs.dtype());120}121122#[cfg(feature = "algorithm_group_by")]123fn group_tuples(&self, multithreaded: bool, sorted: bool) -> PolarsResult<GroupsType> {124self.0.physical().group_tuples(multithreaded, sorted)125}126127fn arg_sort_multiple(128&self,129by: &[Column],130options: &SortMultipleOptions,131) -> PolarsResult<IdxCa> {132self.0.physical().arg_sort_multiple(by, options)133}134}135136impl SeriesTrait for SeriesWrap<TimeChunked> {137fn rename(&mut self, name: PlSmallStr) {138self.0.rename(name);139}140141fn chunk_lengths(&self) -> ChunkLenIter<'_> {142self.0.physical().chunk_lengths()143}144fn name(&self) -> &PlSmallStr {145self.0.name()146}147148fn chunks(&self) -> &Vec<ArrayRef> {149self.0.physical().chunks()150}151152unsafe fn chunks_mut(&mut self) -> &mut Vec<ArrayRef> {153self.0.physical_mut().chunks_mut()154}155156fn shrink_to_fit(&mut self) {157self.0.physical_mut().shrink_to_fit()158}159160fn slice(&self, offset: i64, length: usize) -> Series {161self.0.slice(offset, length).into_series()162}163fn split_at(&self, offset: i64) -> (Series, Series) {164let (a, b) = self.0.split_at(offset);165(a.into_series(), b.into_series())166}167168fn _sum_as_f64(&self) -> f64 {169self.0.physical()._sum_as_f64()170}171172fn mean(&self) -> Option<f64> {173self.0.physical().mean()174}175176fn median(&self) -> Option<f64> {177self.0.physical().median()178}179180fn append(&mut self, other: &Series) -> PolarsResult<()> {181polars_ensure!(self.0.dtype() == other.dtype(), append);182let mut other = other.to_physical_repr().into_owned();183self.0184.physical_mut()185.append_owned(std::mem::take(other._get_inner_mut().as_mut()))186}187188fn append_owned(&mut self, mut other: Series) -> PolarsResult<()> {189polars_ensure!(self.0.dtype() == other.dtype(), append);190self.0.physical_mut().append_owned(std::mem::take(191&mut other192._get_inner_mut()193.as_any_mut()194.downcast_mut::<TimeChunked>()195.unwrap()196.phys,197))198}199200fn extend(&mut self, other: &Series) -> PolarsResult<()> {201polars_ensure!(self.0.dtype() == other.dtype(), extend);202// 3 refs203// ref Cow204// ref SeriesTrait205// ref ChunkedArray206let other = other.to_physical_repr();207self.0208.physical_mut()209.extend(other.as_ref().as_ref().as_ref())?;210Ok(())211}212213fn filter(&self, filter: &BooleanChunked) -> PolarsResult<Series> {214self.0215.physical()216.filter(filter)217.map(|ca| ca.into_time().into_series())218}219220fn take(&self, indices: &IdxCa) -> PolarsResult<Series> {221Ok(self.0.physical().take(indices)?.into_time().into_series())222}223224unsafe fn take_unchecked(&self, indices: &IdxCa) -> Series {225self.0226.physical()227.take_unchecked(indices)228.into_time()229.into_series()230}231232fn take_slice(&self, indices: &[IdxSize]) -> PolarsResult<Series> {233Ok(self.0.physical().take(indices)?.into_time().into_series())234}235236unsafe fn take_slice_unchecked(&self, indices: &[IdxSize]) -> Series {237self.0238.physical()239.take_unchecked(indices)240.into_time()241.into_series()242}243244fn len(&self) -> usize {245self.0.len()246}247248fn rechunk(&self) -> Series {249self.0250.physical()251.rechunk()252.into_owned()253.into_time()254.into_series()255}256257fn new_from_index(&self, index: usize, length: usize) -> Series {258self.0259.physical()260.new_from_index(index, length)261.into_time()262.into_series()263}264265fn cast(&self, dtype: &DataType, cast_options: CastOptions) -> PolarsResult<Series> {266match dtype {267DataType::String => Ok(self268.0269.clone()270.into_series()271.time()272.unwrap()273.to_string("%T")274.into_series()),275_ => self.0.cast_with_options(dtype, cast_options),276}277}278279#[inline]280unsafe fn get_unchecked(&self, index: usize) -> AnyValue<'_> {281self.0.get_any_value_unchecked(index)282}283284fn sort_with(&self, options: SortOptions) -> PolarsResult<Series> {285Ok(self286.0287.physical()288.sort_with(options)289.into_time()290.into_series())291}292293fn arg_sort(&self, options: SortOptions) -> IdxCa {294self.0.physical().arg_sort(options)295}296297fn null_count(&self) -> usize {298self.0.null_count()299}300301fn has_nulls(&self) -> bool {302self.0.has_nulls()303}304305#[cfg(feature = "algorithm_group_by")]306fn unique(&self) -> PolarsResult<Series> {307self.0308.physical()309.unique()310.map(|ca| ca.into_time().into_series())311}312313#[cfg(feature = "algorithm_group_by")]314fn n_unique(&self) -> PolarsResult<usize> {315self.0.physical().n_unique()316}317318#[cfg(feature = "algorithm_group_by")]319fn arg_unique(&self) -> PolarsResult<IdxCa> {320self.0.physical().arg_unique()321}322323fn is_null(&self) -> BooleanChunked {324self.0.is_null()325}326327fn is_not_null(&self) -> BooleanChunked {328self.0.is_not_null()329}330331fn reverse(&self) -> Series {332self.0.physical().reverse().into_time().into_series()333}334335fn as_single_ptr(&mut self) -> PolarsResult<usize> {336self.0.physical_mut().as_single_ptr()337}338339fn shift(&self, periods: i64) -> Series {340self.0.physical().shift(periods).into_time().into_series()341}342343fn max_reduce(&self) -> PolarsResult<Scalar> {344let sc = self.0.physical().max_reduce();345let av = sc.value().cast(self.dtype()).into_static();346Ok(Scalar::new(self.dtype().clone(), av))347}348349fn min_reduce(&self) -> PolarsResult<Scalar> {350let sc = self.0.physical().min_reduce();351let av = sc.value().cast(self.dtype()).into_static();352Ok(Scalar::new(self.dtype().clone(), av))353}354355fn median_reduce(&self) -> PolarsResult<Scalar> {356let av = AnyValue::from(self.median().map(|v| v as i64))357.cast(self.dtype())358.into_static();359Ok(Scalar::new(self.dtype().clone(), av))360}361362fn clone_inner(&self) -> Arc<dyn SeriesTrait> {363Arc::new(SeriesWrap(Clone::clone(&self.0)))364}365366fn find_validity_mismatch(&self, other: &Series, idxs: &mut Vec<IdxSize>) {367self.0.physical().find_validity_mismatch(other, idxs)368}369370fn as_any(&self) -> &dyn Any {371&self.0372}373374fn as_any_mut(&mut self) -> &mut dyn Any {375&mut self.0376}377378fn as_phys_any(&self) -> &dyn Any {379self.0.physical()380}381382fn as_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {383self as _384}385}386387impl private::PrivateSeriesNumeric for SeriesWrap<TimeChunked> {388fn bit_repr(&self) -> Option<BitRepr> {389Some(self.0.physical().to_bit_repr())390}391}392393394