Path: blob/main/crates/polars-core/src/series/implementations/datetime.rs
6940 views
use polars_compute::rolling::QuantileMethod;12use super::*;3#[cfg(feature = "algorithm_group_by")]4use crate::frame::group_by::*;5use crate::prelude::*;67unsafe impl IntoSeries for DatetimeChunked {8fn into_series(self) -> Series {9Series(Arc::new(SeriesWrap(self)))10}11}1213impl private::PrivateSeriesNumeric for SeriesWrap<DatetimeChunked> {14fn bit_repr(&self) -> Option<BitRepr> {15Some(self.0.physical().to_bit_repr())16}17}1819impl private::PrivateSeries for SeriesWrap<DatetimeChunked> {20fn compute_len(&mut self) {21self.0.physical_mut().compute_len()22}23fn _field(&self) -> Cow<'_, Field> {24Cow::Owned(self.0.field())25}26fn _dtype(&self) -> &DataType {27self.0.dtype()28}29fn _get_flags(&self) -> StatisticsFlags {30self.0.physical().get_flags()31}32fn _set_flags(&mut self, flags: StatisticsFlags) {33self.0.physical_mut().set_flags(flags)34}3536#[cfg(feature = "zip_with")]37fn zip_with_same_type(&self, mask: &BooleanChunked, other: &Series) -> PolarsResult<Series> {38let other = other.to_physical_repr().into_owned();39self.040.physical()41.zip_with(mask, other.as_ref().as_ref())42.map(|ca| {43ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())44.into_series()45})46}4748fn into_total_eq_inner<'a>(&'a self) -> Box<dyn TotalEqInner + 'a> {49self.0.physical().into_total_eq_inner()50}51fn into_total_ord_inner<'a>(&'a self) -> Box<dyn TotalOrdInner + 'a> {52self.0.physical().into_total_ord_inner()53}5455fn vec_hash(56&self,57random_state: PlSeedableRandomStateQuality,58buf: &mut Vec<u64>,59) -> PolarsResult<()> {60self.0.physical().vec_hash(random_state, buf)?;61Ok(())62}6364fn vec_hash_combine(65&self,66build_hasher: PlSeedableRandomStateQuality,67hashes: &mut [u64],68) -> PolarsResult<()> {69self.0.physical().vec_hash_combine(build_hasher, hashes)?;70Ok(())71}7273#[cfg(feature = "algorithm_group_by")]74unsafe fn agg_min(&self, groups: &GroupsType) -> Series {75self.076.physical()77.agg_min(groups)78.into_datetime(self.0.time_unit(), self.0.time_zone().clone())79.into_series()80}8182#[cfg(feature = "algorithm_group_by")]83unsafe fn agg_max(&self, groups: &GroupsType) -> Series {84self.085.physical()86.agg_max(groups)87.into_datetime(self.0.time_unit(), self.0.time_zone().clone())88.into_series()89}90#[cfg(feature = "algorithm_group_by")]91unsafe fn agg_list(&self, groups: &GroupsType) -> Series {92// we cannot cast and dispatch as the inner type of the list would be incorrect93self.094.physical()95.agg_list(groups)96.cast(&DataType::List(Box::new(self.dtype().clone())))97.unwrap()98}99100fn subtract(&self, rhs: &Series) -> PolarsResult<Series> {101match (self.dtype(), rhs.dtype()) {102(DataType::Datetime(tu, tz), DataType::Datetime(tur, tzr)) => {103assert_eq!(tu, tur);104assert_eq!(tz, tzr);105let lhs = self.cast(&DataType::Int64, CastOptions::NonStrict).unwrap();106let rhs = rhs.cast(&DataType::Int64).unwrap();107Ok(lhs.subtract(&rhs)?.into_duration(*tu).into_series())108},109(DataType::Datetime(tu, tz), DataType::Duration(tur)) => {110assert_eq!(tu, tur);111let lhs = self.cast(&DataType::Int64, CastOptions::NonStrict).unwrap();112let rhs = rhs.cast(&DataType::Int64).unwrap();113Ok(lhs114.subtract(&rhs)?115.into_datetime(*tu, tz.clone())116.into_series())117},118(dtl, dtr) => polars_bail!(opq = sub, dtl, dtr),119}120}121fn add_to(&self, rhs: &Series) -> PolarsResult<Series> {122match (self.dtype(), rhs.dtype()) {123(DataType::Datetime(tu, tz), DataType::Duration(tur)) => {124assert_eq!(tu, tur);125let lhs = self.cast(&DataType::Int64, CastOptions::NonStrict).unwrap();126let rhs = rhs.cast(&DataType::Int64).unwrap();127Ok(lhs128.add_to(&rhs)?129.into_datetime(*tu, tz.clone())130.into_series())131},132(dtl, dtr) => polars_bail!(opq = add, dtl, dtr),133}134}135fn multiply(&self, rhs: &Series) -> PolarsResult<Series> {136polars_bail!(opq = mul, self.dtype(), rhs.dtype());137}138fn divide(&self, rhs: &Series) -> PolarsResult<Series> {139polars_bail!(opq = div, self.dtype(), rhs.dtype());140}141fn remainder(&self, rhs: &Series) -> PolarsResult<Series> {142polars_bail!(opq = rem, self.dtype(), rhs.dtype());143}144#[cfg(feature = "algorithm_group_by")]145fn group_tuples(&self, multithreaded: bool, sorted: bool) -> PolarsResult<GroupsType> {146self.0.physical().group_tuples(multithreaded, sorted)147}148149fn arg_sort_multiple(150&self,151by: &[Column],152options: &SortMultipleOptions,153) -> PolarsResult<IdxCa> {154self.0.physical().arg_sort_multiple(by, options)155}156}157158impl SeriesTrait for SeriesWrap<DatetimeChunked> {159fn rename(&mut self, name: PlSmallStr) {160self.0.rename(name);161}162163fn chunk_lengths(&self) -> ChunkLenIter<'_> {164self.0.physical().chunk_lengths()165}166fn name(&self) -> &PlSmallStr {167self.0.name()168}169170fn chunks(&self) -> &Vec<ArrayRef> {171self.0.physical().chunks()172}173unsafe fn chunks_mut(&mut self) -> &mut Vec<ArrayRef> {174self.0.physical_mut().chunks_mut()175}176177fn shrink_to_fit(&mut self) {178self.0.physical_mut().shrink_to_fit()179}180181fn slice(&self, offset: i64, length: usize) -> Series {182self.0.slice(offset, length).into_series()183}184fn 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}208fn append_owned(&mut self, mut other: Series) -> PolarsResult<()> {209polars_ensure!(self.0.dtype() == other.dtype(), append);210self.0.physical_mut().append_owned(std::mem::take(211&mut other212._get_inner_mut()213.as_any_mut()214.downcast_mut::<DatetimeChunked>()215.unwrap()216.phys,217))218}219220fn extend(&mut self, other: &Series) -> PolarsResult<()> {221polars_ensure!(self.0.dtype() == other.dtype(), extend);222let other = other.to_physical_repr();223self.0224.physical_mut()225.extend(other.as_ref().as_ref().as_ref())?;226Ok(())227}228229fn filter(&self, filter: &BooleanChunked) -> PolarsResult<Series> {230self.0.physical().filter(filter).map(|ca| {231ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())232.into_series()233})234}235236fn take(&self, indices: &IdxCa) -> PolarsResult<Series> {237let ca = self.0.physical().take(indices)?;238Ok(ca239.into_datetime(self.0.time_unit(), self.0.time_zone().clone())240.into_series())241}242243unsafe fn take_unchecked(&self, indices: &IdxCa) -> Series {244let ca = self.0.physical().take_unchecked(indices);245ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())246.into_series()247}248249fn take_slice(&self, indices: &[IdxSize]) -> PolarsResult<Series> {250let ca = self.0.physical().take(indices)?;251Ok(ca252.into_datetime(self.0.time_unit(), self.0.time_zone().clone())253.into_series())254}255256unsafe fn take_slice_unchecked(&self, indices: &[IdxSize]) -> Series {257let ca = self.0.physical().take_unchecked(indices);258ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())259.into_series()260}261262fn len(&self) -> usize {263self.0.len()264}265266fn rechunk(&self) -> Series {267self.0268.physical()269.rechunk()270.into_owned()271.into_datetime(self.0.time_unit(), self.0.time_zone().clone())272.into_series()273}274275fn new_from_index(&self, index: usize, length: usize) -> Series {276self.0277.physical()278.new_from_index(index, length)279.into_datetime(self.0.time_unit(), self.0.time_zone().clone())280.into_series()281}282283fn cast(&self, dtype: &DataType, cast_options: CastOptions) -> PolarsResult<Series> {284match dtype {285DataType::String => Ok(self.0.to_string("iso")?.into_series()),286_ => self.0.cast_with_options(dtype, cast_options),287}288}289290#[inline]291unsafe fn get_unchecked(&self, index: usize) -> AnyValue<'_> {292self.0.get_any_value_unchecked(index)293}294295fn sort_with(&self, options: SortOptions) -> PolarsResult<Series> {296Ok(self297.0298.physical()299.sort_with(options)300.into_datetime(self.0.time_unit(), self.0.time_zone().clone())301.into_series())302}303304fn arg_sort(&self, options: SortOptions) -> IdxCa {305self.0.physical().arg_sort(options)306}307308fn null_count(&self) -> usize {309self.0.null_count()310}311312fn has_nulls(&self) -> bool {313self.0.has_nulls()314}315316#[cfg(feature = "algorithm_group_by")]317fn unique(&self) -> PolarsResult<Series> {318self.0.physical().unique().map(|ca| {319ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())320.into_series()321})322}323324#[cfg(feature = "algorithm_group_by")]325fn n_unique(&self) -> PolarsResult<usize> {326self.0.physical().n_unique()327}328329#[cfg(feature = "algorithm_group_by")]330fn arg_unique(&self) -> PolarsResult<IdxCa> {331self.0.physical().arg_unique()332}333334fn is_null(&self) -> BooleanChunked {335self.0.is_null()336}337338fn is_not_null(&self) -> BooleanChunked {339self.0.is_not_null()340}341342fn reverse(&self) -> Series {343self.0344.physical()345.reverse()346.into_datetime(self.0.time_unit(), self.0.time_zone().clone())347.into_series()348}349350fn as_single_ptr(&mut self) -> PolarsResult<usize> {351self.0.physical_mut().as_single_ptr()352}353354fn shift(&self, periods: i64) -> Series {355self.0356.physical()357.shift(periods)358.into_datetime(self.0.time_unit(), self.0.time_zone().clone())359.into_series()360}361362fn max_reduce(&self) -> PolarsResult<Scalar> {363let sc = self.0.physical().max_reduce();364365Ok(Scalar::new(self.dtype().clone(), sc.value().clone()))366}367368fn min_reduce(&self) -> PolarsResult<Scalar> {369let sc = self.0.physical().min_reduce();370371Ok(Scalar::new(self.dtype().clone(), sc.value().clone()))372}373374fn median_reduce(&self) -> PolarsResult<Scalar> {375let av: AnyValue = self.median().map(|v| v as i64).into();376Ok(Scalar::new(self.dtype().clone(), av))377}378379fn quantile_reduce(&self, _quantile: f64, _method: QuantileMethod) -> PolarsResult<Scalar> {380Ok(Scalar::new(self.dtype().clone(), AnyValue::Null))381}382383fn clone_inner(&self) -> Arc<dyn SeriesTrait> {384Arc::new(SeriesWrap(Clone::clone(&self.0)))385}386387fn find_validity_mismatch(&self, other: &Series, idxs: &mut Vec<IdxSize>) {388self.0.physical().find_validity_mismatch(other, idxs)389}390391fn as_any(&self) -> &dyn Any {392&self.0393}394395fn as_any_mut(&mut self) -> &mut dyn Any {396&mut self.0397}398399fn as_phys_any(&self) -> &dyn Any {400self.0.physical()401}402403fn as_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {404self as _405}406}407408409