Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-core/src/series/implementations/date.rs
6940 views
1
//! This module exists to reduce compilation times.
2
//!
3
//! All the data types are backed by a physical type in memory e.g. Date -> i32, Datetime-> i64.
4
//!
5
//! Series lead to code implementations of all traits. Whereas there are a lot of duplicates due to
6
//! data types being backed by the same physical type. In this module we reduce compile times by
7
//! opting for a little more run time cost. We cast to the physical type -> apply the operation and
8
//! (depending on the result) cast back to the original type
9
//!
10
use super::*;
11
#[cfg(feature = "algorithm_group_by")]
12
use crate::frame::group_by::*;
13
use crate::prelude::*;
14
15
unsafe impl IntoSeries for DateChunked {
16
fn into_series(self) -> Series {
17
Series(Arc::new(SeriesWrap(self)))
18
}
19
}
20
21
impl private::PrivateSeries for SeriesWrap<DateChunked> {
22
fn compute_len(&mut self) {
23
self.0.physical_mut().compute_len()
24
}
25
26
fn _field(&self) -> Cow<'_, Field> {
27
Cow::Owned(self.0.field())
28
}
29
30
fn _dtype(&self) -> &DataType {
31
self.0.dtype()
32
}
33
34
fn _get_flags(&self) -> StatisticsFlags {
35
self.0.physical().get_flags()
36
}
37
38
fn _set_flags(&mut self, flags: StatisticsFlags) {
39
self.0.physical_mut().set_flags(flags)
40
}
41
42
#[cfg(feature = "zip_with")]
43
fn zip_with_same_type(&self, mask: &BooleanChunked, other: &Series) -> PolarsResult<Series> {
44
let other = other.to_physical_repr().into_owned();
45
self.0
46
.physical()
47
.zip_with(mask, other.as_ref().as_ref())
48
.map(|ca| ca.into_date().into_series())
49
}
50
51
fn into_total_eq_inner<'a>(&'a self) -> Box<dyn TotalEqInner + 'a> {
52
self.0.physical().into_total_eq_inner()
53
}
54
55
fn into_total_ord_inner<'a>(&'a self) -> Box<dyn TotalOrdInner + 'a> {
56
self.0.physical().into_total_ord_inner()
57
}
58
59
fn vec_hash(
60
&self,
61
random_state: PlSeedableRandomStateQuality,
62
buf: &mut Vec<u64>,
63
) -> PolarsResult<()> {
64
self.0.physical().vec_hash(random_state, buf)?;
65
Ok(())
66
}
67
68
fn vec_hash_combine(
69
&self,
70
build_hasher: PlSeedableRandomStateQuality,
71
hashes: &mut [u64],
72
) -> PolarsResult<()> {
73
self.0.physical().vec_hash_combine(build_hasher, hashes)?;
74
Ok(())
75
}
76
77
#[cfg(feature = "algorithm_group_by")]
78
unsafe fn agg_min(&self, groups: &GroupsType) -> Series {
79
self.0.physical().agg_min(groups).into_date().into_series()
80
}
81
82
#[cfg(feature = "algorithm_group_by")]
83
unsafe fn agg_max(&self, groups: &GroupsType) -> Series {
84
self.0.physical().agg_max(groups).into_date().into_series()
85
}
86
87
#[cfg(feature = "algorithm_group_by")]
88
unsafe fn agg_list(&self, groups: &GroupsType) -> Series {
89
// we cannot cast and dispatch as the inner type of the list would be incorrect
90
self.0
91
.physical()
92
.agg_list(groups)
93
.cast(&DataType::List(Box::new(self.dtype().clone())))
94
.unwrap()
95
}
96
97
fn subtract(&self, rhs: &Series) -> PolarsResult<Series> {
98
match rhs.dtype() {
99
DataType::Date => {
100
let dt = DataType::Datetime(TimeUnit::Microseconds, None);
101
let lhs = self.cast(&dt, CastOptions::NonStrict)?;
102
let rhs = rhs.cast(&dt)?;
103
lhs.subtract(&rhs)
104
},
105
DataType::Duration(_) => std::ops::Sub::sub(
106
&self.cast(
107
&DataType::Datetime(TimeUnit::Microseconds, None),
108
CastOptions::NonStrict,
109
)?,
110
rhs,
111
)?
112
.cast(&DataType::Date),
113
dtr => polars_bail!(opq = sub, DataType::Date, dtr),
114
}
115
}
116
117
fn add_to(&self, rhs: &Series) -> PolarsResult<Series> {
118
match rhs.dtype() {
119
DataType::Duration(_) => std::ops::Add::add(
120
&self.cast(
121
&DataType::Datetime(TimeUnit::Microseconds, None),
122
CastOptions::NonStrict,
123
)?,
124
rhs,
125
)?
126
.cast(&DataType::Date),
127
dtr => polars_bail!(opq = add, DataType::Date, dtr),
128
}
129
}
130
131
fn multiply(&self, rhs: &Series) -> PolarsResult<Series> {
132
polars_bail!(opq = mul, self.0.dtype(), rhs.dtype());
133
}
134
135
fn divide(&self, rhs: &Series) -> PolarsResult<Series> {
136
polars_bail!(opq = div, self.0.dtype(), rhs.dtype());
137
}
138
139
fn remainder(&self, rhs: &Series) -> PolarsResult<Series> {
140
polars_bail!(opq = rem, self.0.dtype(), rhs.dtype());
141
}
142
#[cfg(feature = "algorithm_group_by")]
143
fn group_tuples(&self, multithreaded: bool, sorted: bool) -> PolarsResult<GroupsType> {
144
self.0.physical().group_tuples(multithreaded, sorted)
145
}
146
147
fn arg_sort_multiple(
148
&self,
149
by: &[Column],
150
options: &SortMultipleOptions,
151
) -> PolarsResult<IdxCa> {
152
self.0.physical().arg_sort_multiple(by, options)
153
}
154
}
155
156
impl SeriesTrait for SeriesWrap<DateChunked> {
157
fn rename(&mut self, name: PlSmallStr) {
158
self.0.rename(name);
159
}
160
161
fn chunk_lengths(&self) -> ChunkLenIter<'_> {
162
self.0.physical().chunk_lengths()
163
}
164
165
fn name(&self) -> &PlSmallStr {
166
self.0.name()
167
}
168
169
fn chunks(&self) -> &Vec<ArrayRef> {
170
self.0.physical().chunks()
171
}
172
173
unsafe fn chunks_mut(&mut self) -> &mut Vec<ArrayRef> {
174
self.0.physical_mut().chunks_mut()
175
}
176
177
fn shrink_to_fit(&mut self) {
178
self.0.physical_mut().shrink_to_fit()
179
}
180
181
fn slice(&self, offset: i64, length: usize) -> Series {
182
self.0.slice(offset, length).into_series()
183
}
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
210
fn append_owned(&mut self, mut other: Series) -> PolarsResult<()> {
211
polars_ensure!(self.0.dtype() == other.dtype(), append);
212
self.0.physical_mut().append_owned(std::mem::take(
213
&mut other
214
._get_inner_mut()
215
.as_any_mut()
216
.downcast_mut::<DateChunked>()
217
.unwrap()
218
.phys,
219
))
220
}
221
222
fn extend(&mut self, other: &Series) -> PolarsResult<()> {
223
polars_ensure!(self.0.dtype() == other.dtype(), extend);
224
// 3 refs
225
// ref Cow
226
// ref SeriesTrait
227
// ref ChunkedArray
228
let other = other.to_physical_repr();
229
self.0
230
.physical_mut()
231
.extend(other.as_ref().as_ref().as_ref())?;
232
Ok(())
233
}
234
235
fn filter(&self, filter: &BooleanChunked) -> PolarsResult<Series> {
236
self.0
237
.physical()
238
.filter(filter)
239
.map(|ca| ca.into_date().into_series())
240
}
241
242
fn take(&self, indices: &IdxCa) -> PolarsResult<Series> {
243
Ok(self.0.physical().take(indices)?.into_date().into_series())
244
}
245
246
unsafe fn take_unchecked(&self, indices: &IdxCa) -> Series {
247
self.0
248
.physical()
249
.take_unchecked(indices)
250
.into_date()
251
.into_series()
252
}
253
254
fn take_slice(&self, indices: &[IdxSize]) -> PolarsResult<Series> {
255
Ok(self.0.physical().take(indices)?.into_date().into_series())
256
}
257
258
unsafe fn take_slice_unchecked(&self, indices: &[IdxSize]) -> Series {
259
self.0
260
.physical()
261
.take_unchecked(indices)
262
.into_date()
263
.into_series()
264
}
265
266
fn len(&self) -> usize {
267
self.0.len()
268
}
269
270
fn rechunk(&self) -> Series {
271
self.0
272
.physical()
273
.rechunk()
274
.into_owned()
275
.into_date()
276
.into_series()
277
}
278
279
fn new_from_index(&self, index: usize, length: usize) -> Series {
280
self.0
281
.physical()
282
.new_from_index(index, length)
283
.into_date()
284
.into_series()
285
}
286
287
fn cast(&self, dtype: &DataType, cast_options: CastOptions) -> PolarsResult<Series> {
288
match dtype {
289
DataType::String => Ok(self
290
.0
291
.clone()
292
.into_series()
293
.date()
294
.unwrap()
295
.to_string("%Y-%m-%d")?
296
.into_series()),
297
#[cfg(feature = "dtype-datetime")]
298
DataType::Datetime(_, _) => {
299
let mut out = self.0.cast_with_options(dtype, CastOptions::NonStrict)?;
300
out.set_sorted_flag(self.0.physical().is_sorted_flag());
301
Ok(out)
302
},
303
_ => self.0.cast_with_options(dtype, cast_options),
304
}
305
}
306
307
#[inline]
308
unsafe fn get_unchecked(&self, index: usize) -> AnyValue<'_> {
309
self.0.get_any_value_unchecked(index)
310
}
311
312
fn sort_with(&self, options: SortOptions) -> PolarsResult<Series> {
313
Ok(self
314
.0
315
.physical()
316
.sort_with(options)
317
.into_date()
318
.into_series())
319
}
320
321
fn arg_sort(&self, options: SortOptions) -> IdxCa {
322
self.0.physical().arg_sort(options)
323
}
324
325
fn null_count(&self) -> usize {
326
self.0.null_count()
327
}
328
329
fn has_nulls(&self) -> bool {
330
self.0.has_nulls()
331
}
332
333
#[cfg(feature = "algorithm_group_by")]
334
fn unique(&self) -> PolarsResult<Series> {
335
self.0
336
.physical()
337
.unique()
338
.map(|ca| ca.into_date().into_series())
339
}
340
341
#[cfg(feature = "algorithm_group_by")]
342
fn n_unique(&self) -> PolarsResult<usize> {
343
self.0.physical().n_unique()
344
}
345
346
#[cfg(feature = "algorithm_group_by")]
347
fn arg_unique(&self) -> PolarsResult<IdxCa> {
348
self.0.physical().arg_unique()
349
}
350
351
fn is_null(&self) -> BooleanChunked {
352
self.0.is_null()
353
}
354
355
fn is_not_null(&self) -> BooleanChunked {
356
self.0.is_not_null()
357
}
358
359
fn reverse(&self) -> Series {
360
self.0.physical().reverse().into_date().into_series()
361
}
362
363
fn as_single_ptr(&mut self) -> PolarsResult<usize> {
364
self.0.physical_mut().as_single_ptr()
365
}
366
367
fn shift(&self, periods: i64) -> Series {
368
self.0.physical().shift(periods).into_date().into_series()
369
}
370
371
fn max_reduce(&self) -> PolarsResult<Scalar> {
372
let sc = self.0.physical().max_reduce();
373
let av = sc.value().cast(self.dtype()).into_static();
374
Ok(Scalar::new(self.dtype().clone(), av))
375
}
376
377
fn min_reduce(&self) -> PolarsResult<Scalar> {
378
let sc = self.0.physical().min_reduce();
379
let av = sc.value().cast(self.dtype()).into_static();
380
Ok(Scalar::new(self.dtype().clone(), av))
381
}
382
383
fn median_reduce(&self) -> PolarsResult<Scalar> {
384
let av: AnyValue = self
385
.median()
386
.map(|v| (v * (US_IN_DAY as f64)) as i64)
387
.into();
388
Ok(Scalar::new(
389
DataType::Datetime(TimeUnit::Microseconds, None),
390
av,
391
))
392
}
393
394
fn clone_inner(&self) -> Arc<dyn SeriesTrait> {
395
Arc::new(SeriesWrap(Clone::clone(&self.0)))
396
}
397
398
fn find_validity_mismatch(&self, other: &Series, idxs: &mut Vec<IdxSize>) {
399
self.0.physical().find_validity_mismatch(other, idxs)
400
}
401
402
fn as_any(&self) -> &dyn Any {
403
&self.0
404
}
405
406
fn as_any_mut(&mut self) -> &mut dyn Any {
407
&mut self.0
408
}
409
410
fn as_phys_any(&self) -> &dyn Any {
411
self.0.physical()
412
}
413
414
fn as_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
415
self as _
416
}
417
}
418
419
impl private::PrivateSeriesNumeric for SeriesWrap<DateChunked> {
420
fn bit_repr(&self) -> Option<BitRepr> {
421
Some(self.0.physical().to_bit_repr())
422
}
423
}
424
425