polars_core/series/implementations/
datetime.rs1use polars_compute::rolling::QuantileMethod;
2
3use super::*;
4#[cfg(feature = "algorithm_group_by")]
5use crate::frame::group_by::*;
6use crate::prelude::*;
7
8unsafe impl IntoSeries for DatetimeChunked {
9 fn into_series(self) -> Series {
10 Series(Arc::new(SeriesWrap(self)))
11 }
12}
13
14impl private::PrivateSeriesNumeric for SeriesWrap<DatetimeChunked> {
15 fn bit_repr(&self) -> Option<BitRepr> {
16 Some(self.0.physical().to_bit_repr())
17 }
18}
19
20impl private::PrivateSeries for SeriesWrap<DatetimeChunked> {
21 fn compute_len(&mut self) {
22 self.0.physical_mut().compute_len()
23 }
24 fn _field(&self) -> Cow<'_, Field> {
25 Cow::Owned(self.0.field())
26 }
27 fn _dtype(&self) -> &DataType {
28 self.0.dtype()
29 }
30 fn _get_flags(&self) -> StatisticsFlags {
31 self.0.physical().get_flags()
32 }
33 fn _set_flags(&mut self, flags: StatisticsFlags) {
34 self.0.physical_mut().set_flags(flags)
35 }
36
37 #[cfg(feature = "zip_with")]
38 fn zip_with_same_type(&self, mask: &BooleanChunked, other: &Series) -> PolarsResult<Series> {
39 let other = other.to_physical_repr().into_owned();
40 self.0
41 .physical()
42 .zip_with(mask, other.as_ref().as_ref())
43 .map(|ca| {
44 ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())
45 .into_series()
46 })
47 }
48
49 fn into_total_eq_inner<'a>(&'a self) -> Box<dyn TotalEqInner + 'a> {
50 self.0.physical().into_total_eq_inner()
51 }
52 fn into_total_ord_inner<'a>(&'a self) -> Box<dyn TotalOrdInner + 'a> {
53 self.0.physical().into_total_ord_inner()
54 }
55
56 fn vec_hash(
57 &self,
58 random_state: PlSeedableRandomStateQuality,
59 buf: &mut Vec<u64>,
60 ) -> PolarsResult<()> {
61 self.0.physical().vec_hash(random_state, buf)?;
62 Ok(())
63 }
64
65 fn vec_hash_combine(
66 &self,
67 build_hasher: PlSeedableRandomStateQuality,
68 hashes: &mut [u64],
69 ) -> PolarsResult<()> {
70 self.0.physical().vec_hash_combine(build_hasher, hashes)?;
71 Ok(())
72 }
73
74 #[cfg(feature = "algorithm_group_by")]
75 unsafe fn agg_min(&self, groups: &GroupsType) -> Series {
76 self.0
77 .physical()
78 .agg_min(groups)
79 .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
80 .into_series()
81 }
82
83 #[cfg(feature = "algorithm_group_by")]
84 unsafe fn agg_max(&self, groups: &GroupsType) -> Series {
85 self.0
86 .physical()
87 .agg_max(groups)
88 .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
89 .into_series()
90 }
91 #[cfg(feature = "algorithm_group_by")]
92 unsafe fn agg_list(&self, groups: &GroupsType) -> Series {
93 self.0
95 .physical()
96 .agg_list(groups)
97 .cast(&DataType::List(Box::new(self.dtype().clone())))
98 .unwrap()
99 }
100
101 fn subtract(&self, rhs: &Series) -> PolarsResult<Series> {
102 match (self.dtype(), rhs.dtype()) {
103 (DataType::Datetime(tu, tz), DataType::Datetime(tur, tzr)) => {
104 assert_eq!(tu, tur);
105 assert_eq!(tz, tzr);
106 let lhs = self.cast(&DataType::Int64, CastOptions::NonStrict).unwrap();
107 let rhs = rhs.cast(&DataType::Int64).unwrap();
108 Ok(lhs.subtract(&rhs)?.into_duration(*tu).into_series())
109 },
110 (DataType::Datetime(tu, tz), DataType::Duration(tur)) => {
111 assert_eq!(tu, tur);
112 let lhs = self.cast(&DataType::Int64, CastOptions::NonStrict).unwrap();
113 let rhs = rhs.cast(&DataType::Int64).unwrap();
114 Ok(lhs
115 .subtract(&rhs)?
116 .into_datetime(*tu, tz.clone())
117 .into_series())
118 },
119 (dtl, dtr) => polars_bail!(opq = sub, dtl, dtr),
120 }
121 }
122 fn add_to(&self, rhs: &Series) -> PolarsResult<Series> {
123 match (self.dtype(), rhs.dtype()) {
124 (DataType::Datetime(tu, tz), DataType::Duration(tur)) => {
125 assert_eq!(tu, tur);
126 let lhs = self.cast(&DataType::Int64, CastOptions::NonStrict).unwrap();
127 let rhs = rhs.cast(&DataType::Int64).unwrap();
128 Ok(lhs
129 .add_to(&rhs)?
130 .into_datetime(*tu, tz.clone())
131 .into_series())
132 },
133 (dtl, dtr) => polars_bail!(opq = add, dtl, dtr),
134 }
135 }
136 fn multiply(&self, rhs: &Series) -> PolarsResult<Series> {
137 polars_bail!(opq = mul, self.dtype(), rhs.dtype());
138 }
139 fn divide(&self, rhs: &Series) -> PolarsResult<Series> {
140 polars_bail!(opq = div, self.dtype(), rhs.dtype());
141 }
142 fn remainder(&self, rhs: &Series) -> PolarsResult<Series> {
143 polars_bail!(opq = rem, self.dtype(), rhs.dtype());
144 }
145 #[cfg(feature = "algorithm_group_by")]
146 fn group_tuples(&self, multithreaded: bool, sorted: bool) -> PolarsResult<GroupsType> {
147 self.0.physical().group_tuples(multithreaded, sorted)
148 }
149
150 fn arg_sort_multiple(
151 &self,
152 by: &[Column],
153 options: &SortMultipleOptions,
154 ) -> PolarsResult<IdxCa> {
155 self.0.physical().arg_sort_multiple(by, options)
156 }
157}
158
159impl SeriesTrait for SeriesWrap<DatetimeChunked> {
160 fn rename(&mut self, name: PlSmallStr) {
161 self.0.rename(name);
162 }
163
164 fn chunk_lengths(&self) -> ChunkLenIter<'_> {
165 self.0.physical().chunk_lengths()
166 }
167 fn name(&self) -> &PlSmallStr {
168 self.0.name()
169 }
170
171 fn chunks(&self) -> &Vec<ArrayRef> {
172 self.0.physical().chunks()
173 }
174 unsafe fn chunks_mut(&mut self) -> &mut Vec<ArrayRef> {
175 self.0.physical_mut().chunks_mut()
176 }
177
178 fn shrink_to_fit(&mut self) {
179 self.0.physical_mut().shrink_to_fit()
180 }
181
182 fn slice(&self, offset: i64, length: usize) -> Series {
183 self.0.slice(offset, length).into_series()
184 }
185 fn split_at(&self, offset: i64) -> (Series, Series) {
186 let (a, b) = self.0.split_at(offset);
187 (a.into_series(), b.into_series())
188 }
189
190 fn _sum_as_f64(&self) -> f64 {
191 self.0.physical()._sum_as_f64()
192 }
193
194 fn mean(&self) -> Option<f64> {
195 self.0.physical().mean()
196 }
197
198 fn median(&self) -> Option<f64> {
199 self.0.physical().median()
200 }
201
202 fn append(&mut self, other: &Series) -> PolarsResult<()> {
203 polars_ensure!(self.0.dtype() == other.dtype(), append);
204 let mut other = other.to_physical_repr().into_owned();
205 self.0
206 .physical_mut()
207 .append_owned(std::mem::take(other._get_inner_mut().as_mut()))
208 }
209 fn append_owned(&mut self, mut other: Series) -> PolarsResult<()> {
210 polars_ensure!(self.0.dtype() == other.dtype(), append);
211 self.0.physical_mut().append_owned(std::mem::take(
212 &mut other
213 ._get_inner_mut()
214 .as_any_mut()
215 .downcast_mut::<DatetimeChunked>()
216 .unwrap()
217 .phys,
218 ))
219 }
220
221 fn extend(&mut self, other: &Series) -> PolarsResult<()> {
222 polars_ensure!(self.0.dtype() == other.dtype(), extend);
223 let other = other.to_physical_repr();
224 self.0
225 .physical_mut()
226 .extend(other.as_ref().as_ref().as_ref())?;
227 Ok(())
228 }
229
230 fn filter(&self, filter: &BooleanChunked) -> PolarsResult<Series> {
231 self.0.physical().filter(filter).map(|ca| {
232 ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())
233 .into_series()
234 })
235 }
236
237 fn take(&self, indices: &IdxCa) -> PolarsResult<Series> {
238 let ca = self.0.physical().take(indices)?;
239 Ok(ca
240 .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
241 .into_series())
242 }
243
244 unsafe fn take_unchecked(&self, indices: &IdxCa) -> Series {
245 let ca = self.0.physical().take_unchecked(indices);
246 ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())
247 .into_series()
248 }
249
250 fn take_slice(&self, indices: &[IdxSize]) -> PolarsResult<Series> {
251 let ca = self.0.physical().take(indices)?;
252 Ok(ca
253 .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
254 .into_series())
255 }
256
257 unsafe fn take_slice_unchecked(&self, indices: &[IdxSize]) -> Series {
258 let ca = self.0.physical().take_unchecked(indices);
259 ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())
260 .into_series()
261 }
262
263 fn len(&self) -> usize {
264 self.0.len()
265 }
266
267 fn rechunk(&self) -> Series {
268 self.0
269 .physical()
270 .rechunk()
271 .into_owned()
272 .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
273 .into_series()
274 }
275
276 fn new_from_index(&self, index: usize, length: usize) -> Series {
277 self.0
278 .physical()
279 .new_from_index(index, length)
280 .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
281 .into_series()
282 }
283
284 fn cast(&self, dtype: &DataType, cast_options: CastOptions) -> PolarsResult<Series> {
285 match dtype {
286 DataType::String => Ok(self.0.to_string("iso")?.into_series()),
287 _ => self.0.cast_with_options(dtype, cast_options),
288 }
289 }
290
291 #[inline]
292 unsafe fn get_unchecked(&self, index: usize) -> AnyValue<'_> {
293 self.0.get_any_value_unchecked(index)
294 }
295
296 fn sort_with(&self, options: SortOptions) -> PolarsResult<Series> {
297 Ok(self
298 .0
299 .physical()
300 .sort_with(options)
301 .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
302 .into_series())
303 }
304
305 fn arg_sort(&self, options: SortOptions) -> IdxCa {
306 self.0.physical().arg_sort(options)
307 }
308
309 fn null_count(&self) -> usize {
310 self.0.null_count()
311 }
312
313 fn has_nulls(&self) -> bool {
314 self.0.has_nulls()
315 }
316
317 #[cfg(feature = "algorithm_group_by")]
318 fn unique(&self) -> PolarsResult<Series> {
319 self.0.physical().unique().map(|ca| {
320 ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())
321 .into_series()
322 })
323 }
324
325 #[cfg(feature = "algorithm_group_by")]
326 fn n_unique(&self) -> PolarsResult<usize> {
327 self.0.physical().n_unique()
328 }
329
330 #[cfg(feature = "algorithm_group_by")]
331 fn arg_unique(&self) -> PolarsResult<IdxCa> {
332 self.0.physical().arg_unique()
333 }
334
335 fn is_null(&self) -> BooleanChunked {
336 self.0.is_null()
337 }
338
339 fn is_not_null(&self) -> BooleanChunked {
340 self.0.is_not_null()
341 }
342
343 fn reverse(&self) -> Series {
344 self.0
345 .physical()
346 .reverse()
347 .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
348 .into_series()
349 }
350
351 fn as_single_ptr(&mut self) -> PolarsResult<usize> {
352 self.0.physical_mut().as_single_ptr()
353 }
354
355 fn shift(&self, periods: i64) -> Series {
356 self.0
357 .physical()
358 .shift(periods)
359 .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
360 .into_series()
361 }
362
363 fn max_reduce(&self) -> PolarsResult<Scalar> {
364 let sc = self.0.physical().max_reduce();
365
366 Ok(Scalar::new(self.dtype().clone(), sc.value().clone()))
367 }
368
369 fn min_reduce(&self) -> PolarsResult<Scalar> {
370 let sc = self.0.physical().min_reduce();
371
372 Ok(Scalar::new(self.dtype().clone(), sc.value().clone()))
373 }
374
375 fn median_reduce(&self) -> PolarsResult<Scalar> {
376 let av: AnyValue = self.median().map(|v| v as i64).into();
377 Ok(Scalar::new(self.dtype().clone(), av))
378 }
379
380 fn quantile_reduce(&self, _quantile: f64, _method: QuantileMethod) -> PolarsResult<Scalar> {
381 Ok(Scalar::new(self.dtype().clone(), AnyValue::Null))
382 }
383
384 fn clone_inner(&self) -> Arc<dyn SeriesTrait> {
385 Arc::new(SeriesWrap(Clone::clone(&self.0)))
386 }
387
388 fn find_validity_mismatch(&self, other: &Series, idxs: &mut Vec<IdxSize>) {
389 self.0.physical().find_validity_mismatch(other, idxs)
390 }
391
392 fn as_any(&self) -> &dyn Any {
393 &self.0
394 }
395
396 fn as_any_mut(&mut self) -> &mut dyn Any {
397 &mut self.0
398 }
399
400 fn as_phys_any(&self) -> &dyn Any {
401 self.0.physical()
402 }
403
404 fn as_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
405 self as _
406 }
407}