Path: blob/main/crates/polars-core/src/series/implementations/datetime.rs
8424 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}9091#[cfg(feature = "algorithm_group_by")]92unsafe fn agg_arg_min(&self, groups: &GroupsType) -> Series {93self.0.physical().agg_arg_min(groups)94}9596#[cfg(feature = "algorithm_group_by")]97unsafe fn agg_arg_max(&self, groups: &GroupsType) -> Series {98self.0.physical().agg_arg_max(groups)99}100101#[cfg(feature = "algorithm_group_by")]102unsafe fn agg_list(&self, groups: &GroupsType) -> Series {103// we cannot cast and dispatch as the inner type of the list would be incorrect104self.0105.physical()106.agg_list(groups)107.cast(&DataType::List(Box::new(self.dtype().clone())))108.unwrap()109}110111fn subtract(&self, rhs: &Series) -> PolarsResult<Series> {112match (self.dtype(), rhs.dtype()) {113(DataType::Datetime(tu, tz), DataType::Datetime(tur, tzr)) => {114assert_eq!(tu, tur);115assert_eq!(tz, tzr);116let lhs = self.cast(&DataType::Int64, CastOptions::NonStrict).unwrap();117let rhs = rhs.cast(&DataType::Int64).unwrap();118Ok(lhs.subtract(&rhs)?.into_duration(*tu).into_series())119},120(DataType::Datetime(tu, tz), DataType::Duration(tur)) => {121assert_eq!(tu, tur);122let lhs = self.cast(&DataType::Int64, CastOptions::NonStrict).unwrap();123let rhs = rhs.cast(&DataType::Int64).unwrap();124Ok(lhs125.subtract(&rhs)?126.into_datetime(*tu, tz.clone())127.into_series())128},129(dtl, dtr) => polars_bail!(opq = sub, dtl, dtr),130}131}132fn add_to(&self, rhs: &Series) -> PolarsResult<Series> {133match (self.dtype(), rhs.dtype()) {134(DataType::Datetime(tu, tz), DataType::Duration(tur)) => {135assert_eq!(tu, tur);136let lhs = self.cast(&DataType::Int64, CastOptions::NonStrict).unwrap();137let rhs = rhs.cast(&DataType::Int64).unwrap();138Ok(lhs139.add_to(&rhs)?140.into_datetime(*tu, tz.clone())141.into_series())142},143(dtl, dtr) => polars_bail!(opq = add, dtl, dtr),144}145}146fn multiply(&self, rhs: &Series) -> PolarsResult<Series> {147polars_bail!(opq = mul, self.dtype(), rhs.dtype());148}149fn divide(&self, rhs: &Series) -> PolarsResult<Series> {150polars_bail!(opq = div, self.dtype(), rhs.dtype());151}152fn remainder(&self, rhs: &Series) -> PolarsResult<Series> {153polars_bail!(opq = rem, self.dtype(), rhs.dtype());154}155#[cfg(feature = "algorithm_group_by")]156fn group_tuples(&self, multithreaded: bool, sorted: bool) -> PolarsResult<GroupsType> {157self.0.physical().group_tuples(multithreaded, sorted)158}159160fn arg_sort_multiple(161&self,162by: &[Column],163options: &SortMultipleOptions,164) -> PolarsResult<IdxCa> {165self.0.physical().arg_sort_multiple(by, options)166}167}168169impl SeriesTrait for SeriesWrap<DatetimeChunked> {170fn rename(&mut self, name: PlSmallStr) {171self.0.rename(name);172}173174fn chunk_lengths(&self) -> ChunkLenIter<'_> {175self.0.physical().chunk_lengths()176}177fn name(&self) -> &PlSmallStr {178self.0.name()179}180181fn chunks(&self) -> &Vec<ArrayRef> {182self.0.physical().chunks()183}184unsafe fn chunks_mut(&mut self) -> &mut Vec<ArrayRef> {185self.0.physical_mut().chunks_mut()186}187188fn shrink_to_fit(&mut self) {189self.0.physical_mut().shrink_to_fit()190}191192fn slice(&self, offset: i64, length: usize) -> Series {193self.0.slice(offset, length).into_series()194}195fn split_at(&self, offset: i64) -> (Series, Series) {196let (a, b) = self.0.split_at(offset);197(a.into_series(), b.into_series())198}199200fn _sum_as_f64(&self) -> f64 {201self.0.physical()._sum_as_f64()202}203204fn mean(&self) -> Option<f64> {205self.0.physical().mean()206}207208fn median(&self) -> Option<f64> {209self.0.physical().median()210}211212fn append(&mut self, other: &Series) -> PolarsResult<()> {213polars_ensure!(self.0.dtype() == other.dtype(), append);214let mut other = other.to_physical_repr().into_owned();215self.0216.physical_mut()217.append_owned(std::mem::take(other._get_inner_mut().as_mut()))218}219fn append_owned(&mut self, mut other: Series) -> PolarsResult<()> {220polars_ensure!(self.0.dtype() == other.dtype(), append);221self.0.physical_mut().append_owned(std::mem::take(222&mut other223._get_inner_mut()224.as_any_mut()225.downcast_mut::<DatetimeChunked>()226.unwrap()227.phys,228))229}230231fn extend(&mut self, other: &Series) -> PolarsResult<()> {232polars_ensure!(self.0.dtype() == other.dtype(), extend);233let other = other.to_physical_repr();234self.0235.physical_mut()236.extend(other.as_ref().as_ref().as_ref())?;237Ok(())238}239240fn filter(&self, filter: &BooleanChunked) -> PolarsResult<Series> {241self.0.physical().filter(filter).map(|ca| {242ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())243.into_series()244})245}246247fn take(&self, indices: &IdxCa) -> PolarsResult<Series> {248let ca = self.0.physical().take(indices)?;249Ok(ca250.into_datetime(self.0.time_unit(), self.0.time_zone().clone())251.into_series())252}253254unsafe fn take_unchecked(&self, indices: &IdxCa) -> Series {255let ca = self.0.physical().take_unchecked(indices);256ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())257.into_series()258}259260fn take_slice(&self, indices: &[IdxSize]) -> PolarsResult<Series> {261let ca = self.0.physical().take(indices)?;262Ok(ca263.into_datetime(self.0.time_unit(), self.0.time_zone().clone())264.into_series())265}266267unsafe fn take_slice_unchecked(&self, indices: &[IdxSize]) -> Series {268let ca = self.0.physical().take_unchecked(indices);269ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())270.into_series()271}272273fn deposit(&self, validity: &Bitmap) -> Series {274self.0275.physical()276.deposit(validity)277.into_datetime(self.0.time_unit(), self.0.time_zone().clone())278.into_series()279}280281fn len(&self) -> usize {282self.0.len()283}284285fn rechunk(&self) -> Series {286self.0287.physical()288.rechunk()289.into_owned()290.into_datetime(self.0.time_unit(), self.0.time_zone().clone())291.into_series()292}293294fn new_from_index(&self, index: usize, length: usize) -> Series {295self.0296.physical()297.new_from_index(index, length)298.into_datetime(self.0.time_unit(), self.0.time_zone().clone())299.into_series()300}301302fn cast(&self, dtype: &DataType, cast_options: CastOptions) -> PolarsResult<Series> {303match dtype {304DataType::String => Ok(self.0.to_string("iso")?.into_series()),305_ => self.0.cast_with_options(dtype, cast_options),306}307}308309#[inline]310unsafe fn get_unchecked(&self, index: usize) -> AnyValue<'_> {311self.0.get_any_value_unchecked(index)312}313314fn sort_with(&self, options: SortOptions) -> PolarsResult<Series> {315Ok(self316.0317.physical()318.sort_with(options)319.into_datetime(self.0.time_unit(), self.0.time_zone().clone())320.into_series())321}322323fn arg_sort(&self, options: SortOptions) -> IdxCa {324self.0.physical().arg_sort(options)325}326327fn null_count(&self) -> usize {328self.0.null_count()329}330331fn has_nulls(&self) -> bool {332self.0.has_nulls()333}334335#[cfg(feature = "algorithm_group_by")]336fn unique(&self) -> PolarsResult<Series> {337self.0.physical().unique().map(|ca| {338ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())339.into_series()340})341}342343#[cfg(feature = "algorithm_group_by")]344fn n_unique(&self) -> PolarsResult<usize> {345self.0.physical().n_unique()346}347348#[cfg(feature = "algorithm_group_by")]349fn arg_unique(&self) -> PolarsResult<IdxCa> {350self.0.physical().arg_unique()351}352353fn unique_id(&self) -> PolarsResult<(IdxSize, Vec<IdxSize>)> {354ChunkUnique::unique_id(self.0.physical())355}356357fn is_null(&self) -> BooleanChunked {358self.0.is_null()359}360361fn is_not_null(&self) -> BooleanChunked {362self.0.is_not_null()363}364365fn reverse(&self) -> Series {366self.0367.physical()368.reverse()369.into_datetime(self.0.time_unit(), self.0.time_zone().clone())370.into_series()371}372373fn as_single_ptr(&mut self) -> PolarsResult<usize> {374self.0.physical_mut().as_single_ptr()375}376377fn shift(&self, periods: i64) -> Series {378self.0379.physical()380.shift(periods)381.into_datetime(self.0.time_unit(), self.0.time_zone().clone())382.into_series()383}384385fn max_reduce(&self) -> PolarsResult<Scalar> {386let sc = self.0.physical().max_reduce();387let av = sc388.value()389.as_datetime_owned(self.0.time_unit(), self.0.time_zone_arc());390Ok(Scalar::new(self.dtype().clone(), av))391}392393fn min_reduce(&self) -> PolarsResult<Scalar> {394let sc = self.0.physical().min_reduce();395let av = sc396.value()397.as_datetime_owned(self.0.time_unit(), self.0.time_zone_arc());398Ok(Scalar::new(self.dtype().clone(), av))399}400401fn mean_reduce(&self) -> PolarsResult<Scalar> {402let mean = self.mean().map(|v| v as i64);403let av = AnyValue::from(mean).as_datetime_owned(self.0.time_unit(), self.0.time_zone_arc());404Ok(Scalar::new(self.dtype().clone(), av))405}406407fn median_reduce(&self) -> PolarsResult<Scalar> {408let median = self.median().map(|v| v as i64);409let av =410AnyValue::from(median).as_datetime_owned(self.0.time_unit(), self.0.time_zone_arc());411Ok(Scalar::new(self.dtype().clone(), av))412}413414fn quantile_reduce(&self, quantile: f64, method: QuantileMethod) -> PolarsResult<Scalar> {415let quantile = self.0.physical().quantile_reduce(quantile, method)?;416let av = quantile.value().cast(&DataType::Int64);417Ok(Scalar::new(418self.dtype().clone(),419av.as_datetime_owned(self.0.time_unit(), self.0.time_zone_arc()),420))421}422423fn quantiles_reduce(&self, quantiles: &[f64], method: QuantileMethod) -> PolarsResult<Scalar> {424let result = self.0.physical().quantiles_reduce(quantiles, method)?;425426if let AnyValue::List(float_s) = result.value() {427let float_ca = float_s.f64().unwrap();428let int_s = float_ca429.iter()430.map(|v: Option<f64>| v.map(|f| f as i64))431.collect::<Int64Chunked>()432.into_datetime(self.0.time_unit(), self.0.time_zone().clone())433.into_series();434Ok(Scalar::new(435DataType::List(Box::new(self.dtype().clone())),436AnyValue::List(int_s),437))438} else {439polars_bail!(ComputeError: "expected list scalar from quantiles_reduce")440}441}442443#[cfg(feature = "approx_unique")]444fn approx_n_unique(&self) -> PolarsResult<IdxSize> {445Ok(ChunkApproxNUnique::approx_n_unique(self.0.physical()))446}447448fn clone_inner(&self) -> Arc<dyn SeriesTrait> {449Arc::new(SeriesWrap(Clone::clone(&self.0)))450}451452fn find_validity_mismatch(&self, other: &Series, idxs: &mut Vec<IdxSize>) {453self.0.physical().find_validity_mismatch(other, idxs)454}455456fn as_any(&self) -> &dyn Any {457&self.0458}459460fn as_any_mut(&mut self) -> &mut dyn Any {461&mut self.0462}463464fn as_phys_any(&self) -> &dyn Any {465self.0.physical()466}467468fn as_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {469self as _470}471}472473474