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/mod.rs
8426 views
1
#![allow(unsafe_op_in_unsafe_fn)]
2
#[cfg(feature = "dtype-array")]
3
mod array;
4
mod binary;
5
mod binary_offset;
6
mod boolean;
7
#[cfg(feature = "dtype-categorical")]
8
mod categorical;
9
#[cfg(feature = "dtype-date")]
10
mod date;
11
#[cfg(feature = "dtype-datetime")]
12
mod datetime;
13
#[cfg(feature = "dtype-decimal")]
14
mod decimal;
15
#[cfg(feature = "dtype-duration")]
16
mod duration;
17
#[cfg(feature = "dtype-extension")]
18
mod extension;
19
mod floats;
20
mod list;
21
pub(crate) mod null;
22
#[cfg(feature = "object")]
23
mod object;
24
mod string;
25
#[cfg(feature = "dtype-struct")]
26
mod struct_;
27
#[cfg(feature = "dtype-time")]
28
mod time;
29
30
use std::any::Any;
31
use std::borrow::Cow;
32
33
use arrow::bitmap::Bitmap;
34
use polars_compute::rolling::QuantileMethod;
35
use polars_utils::aliases::PlSeedableRandomStateQuality;
36
37
use super::*;
38
use crate::chunked_array::AsSinglePtr;
39
use crate::chunked_array::comparison::*;
40
use crate::chunked_array::ops::compare_inner::{
41
IntoTotalEqInner, IntoTotalOrdInner, TotalEqInner, TotalOrdInner,
42
};
43
44
// Utility wrapper struct
45
#[repr(transparent)]
46
pub(crate) struct SeriesWrap<T>(pub T);
47
48
impl<T: PolarsDataType> From<ChunkedArray<T>> for SeriesWrap<ChunkedArray<T>> {
49
fn from(ca: ChunkedArray<T>) -> Self {
50
SeriesWrap(ca)
51
}
52
}
53
54
impl<T: PolarsDataType> Deref for SeriesWrap<ChunkedArray<T>> {
55
type Target = ChunkedArray<T>;
56
57
fn deref(&self) -> &Self::Target {
58
&self.0
59
}
60
}
61
62
unsafe impl<T: PolarsPhysicalType> IntoSeries for ChunkedArray<T> {
63
fn into_series(self) -> Series {
64
T::ca_into_series(self)
65
}
66
}
67
68
macro_rules! impl_dyn_series {
69
($ca: ident, $pdt:ty) => {
70
impl private::PrivateSeries for SeriesWrap<$ca> {
71
fn compute_len(&mut self) {
72
self.0.compute_len()
73
}
74
75
fn _field(&self) -> Cow<'_, Field> {
76
Cow::Borrowed(self.0.ref_field())
77
}
78
79
fn _dtype(&self) -> &DataType {
80
self.0.ref_field().dtype()
81
}
82
83
fn _get_flags(&self) -> StatisticsFlags {
84
self.0.get_flags()
85
}
86
87
fn _set_flags(&mut self, flags: StatisticsFlags) {
88
self.0.set_flags(flags)
89
}
90
91
unsafe fn equal_element(
92
&self,
93
idx_self: usize,
94
idx_other: usize,
95
other: &Series,
96
) -> bool {
97
self.0.equal_element(idx_self, idx_other, other)
98
}
99
100
#[cfg(feature = "zip_with")]
101
fn zip_with_same_type(
102
&self,
103
mask: &BooleanChunked,
104
other: &Series,
105
) -> PolarsResult<Series> {
106
ChunkZip::zip_with(&self.0, mask, other.as_ref().as_ref())
107
.map(|ca| ca.into_series())
108
}
109
fn into_total_eq_inner<'a>(&'a self) -> Box<dyn TotalEqInner + 'a> {
110
(&self.0).into_total_eq_inner()
111
}
112
fn into_total_ord_inner<'a>(&'a self) -> Box<dyn TotalOrdInner + 'a> {
113
(&self.0).into_total_ord_inner()
114
}
115
116
fn vec_hash(
117
&self,
118
random_state: PlSeedableRandomStateQuality,
119
buf: &mut Vec<u64>,
120
) -> PolarsResult<()> {
121
self.0.vec_hash(random_state, buf)?;
122
Ok(())
123
}
124
125
fn vec_hash_combine(
126
&self,
127
build_hasher: PlSeedableRandomStateQuality,
128
hashes: &mut [u64],
129
) -> PolarsResult<()> {
130
self.0.vec_hash_combine(build_hasher, hashes)?;
131
Ok(())
132
}
133
134
#[cfg(feature = "algorithm_group_by")]
135
unsafe fn agg_min(&self, groups: &GroupsType) -> Series {
136
self.0.agg_min(groups)
137
}
138
139
#[cfg(feature = "algorithm_group_by")]
140
unsafe fn agg_max(&self, groups: &GroupsType) -> Series {
141
self.0.agg_max(groups)
142
}
143
144
#[cfg(feature = "algorithm_group_by")]
145
unsafe fn agg_arg_min(&self, groups: &GroupsType) -> Series {
146
self.0.agg_arg_min(groups)
147
}
148
149
#[cfg(feature = "algorithm_group_by")]
150
unsafe fn agg_arg_max(&self, groups: &GroupsType) -> Series {
151
self.0.agg_arg_max(groups)
152
}
153
154
#[cfg(feature = "algorithm_group_by")]
155
unsafe fn agg_sum(&self, groups: &GroupsType) -> Series {
156
use DataType::*;
157
match self.dtype() {
158
Int8 | UInt8 | Int16 | UInt16 => self
159
.cast(&Int64, CastOptions::Overflowing)
160
.unwrap()
161
.agg_sum(groups),
162
_ => self.0.agg_sum(groups),
163
}
164
}
165
166
#[cfg(feature = "algorithm_group_by")]
167
unsafe fn agg_std(&self, groups: &GroupsType, ddof: u8) -> Series {
168
self.0.agg_std(groups, ddof)
169
}
170
171
#[cfg(feature = "algorithm_group_by")]
172
unsafe fn agg_var(&self, groups: &GroupsType, ddof: u8) -> Series {
173
self.0.agg_var(groups, ddof)
174
}
175
176
#[cfg(feature = "algorithm_group_by")]
177
unsafe fn agg_list(&self, groups: &GroupsType) -> Series {
178
self.0.agg_list(groups)
179
}
180
181
#[cfg(feature = "bitwise")]
182
unsafe fn agg_and(&self, groups: &GroupsType) -> Series {
183
self.0.agg_and(groups)
184
}
185
#[cfg(feature = "bitwise")]
186
unsafe fn agg_or(&self, groups: &GroupsType) -> Series {
187
self.0.agg_or(groups)
188
}
189
#[cfg(feature = "bitwise")]
190
unsafe fn agg_xor(&self, groups: &GroupsType) -> Series {
191
self.0.agg_xor(groups)
192
}
193
194
fn subtract(&self, rhs: &Series) -> PolarsResult<Series> {
195
NumOpsDispatch::subtract(&self.0, rhs)
196
}
197
fn add_to(&self, rhs: &Series) -> PolarsResult<Series> {
198
NumOpsDispatch::add_to(&self.0, rhs)
199
}
200
fn multiply(&self, rhs: &Series) -> PolarsResult<Series> {
201
NumOpsDispatch::multiply(&self.0, rhs)
202
}
203
fn divide(&self, rhs: &Series) -> PolarsResult<Series> {
204
NumOpsDispatch::divide(&self.0, rhs)
205
}
206
fn remainder(&self, rhs: &Series) -> PolarsResult<Series> {
207
NumOpsDispatch::remainder(&self.0, rhs)
208
}
209
#[cfg(feature = "algorithm_group_by")]
210
fn group_tuples(&self, multithreaded: bool, sorted: bool) -> PolarsResult<GroupsType> {
211
IntoGroupsType::group_tuples(&self.0, multithreaded, sorted)
212
}
213
214
fn arg_sort_multiple(
215
&self,
216
by: &[Column],
217
options: &SortMultipleOptions,
218
) -> PolarsResult<IdxCa> {
219
self.0.arg_sort_multiple(by, options)
220
}
221
}
222
223
impl SeriesTrait for SeriesWrap<$ca> {
224
#[cfg(feature = "rolling_window")]
225
fn rolling_map(
226
&self,
227
_f: &dyn Fn(&Series) -> PolarsResult<Series>,
228
_options: RollingOptionsFixedWindow,
229
) -> PolarsResult<Series> {
230
ChunkRollApply::rolling_map(&self.0, _f, _options).map(|ca| ca.into_series())
231
}
232
233
fn rename(&mut self, name: PlSmallStr) {
234
self.0.rename(name);
235
}
236
237
fn chunk_lengths(&self) -> ChunkLenIter<'_> {
238
self.0.chunk_lengths()
239
}
240
fn name(&self) -> &PlSmallStr {
241
self.0.name()
242
}
243
244
fn chunks(&self) -> &Vec<ArrayRef> {
245
self.0.chunks()
246
}
247
unsafe fn chunks_mut(&mut self) -> &mut Vec<ArrayRef> {
248
self.0.chunks_mut()
249
}
250
fn shrink_to_fit(&mut self) {
251
self.0.shrink_to_fit()
252
}
253
254
fn slice(&self, offset: i64, length: usize) -> Series {
255
self.0.slice(offset, length).into_series()
256
}
257
258
fn split_at(&self, offset: i64) -> (Series, Series) {
259
let (a, b) = self.0.split_at(offset);
260
(a.into_series(), b.into_series())
261
}
262
263
fn append(&mut self, other: &Series) -> PolarsResult<()> {
264
polars_ensure!(self.0.dtype() == other.dtype(), append);
265
self.0.append(other.as_ref().as_ref())?;
266
Ok(())
267
}
268
fn append_owned(&mut self, other: Series) -> PolarsResult<()> {
269
polars_ensure!(self.0.dtype() == other.dtype(), append);
270
self.0.append_owned(other.take_inner())
271
}
272
273
fn extend(&mut self, other: &Series) -> PolarsResult<()> {
274
polars_ensure!(self.0.dtype() == other.dtype(), extend);
275
self.0.extend(other.as_ref().as_ref())?;
276
Ok(())
277
}
278
279
fn filter(&self, filter: &BooleanChunked) -> PolarsResult<Series> {
280
ChunkFilter::filter(&self.0, filter).map(|ca| ca.into_series())
281
}
282
283
fn _sum_as_f64(&self) -> f64 {
284
self.0._sum_as_f64()
285
}
286
287
fn mean(&self) -> Option<f64> {
288
self.0.mean()
289
}
290
291
fn median(&self) -> Option<f64> {
292
self.0.median()
293
}
294
295
fn std(&self, ddof: u8) -> Option<f64> {
296
self.0.std(ddof)
297
}
298
299
fn var(&self, ddof: u8) -> Option<f64> {
300
self.0.var(ddof)
301
}
302
303
fn take(&self, indices: &IdxCa) -> PolarsResult<Series> {
304
Ok(self.0.take(indices)?.into_series())
305
}
306
307
unsafe fn take_unchecked(&self, indices: &IdxCa) -> Series {
308
self.0.take_unchecked(indices).into_series()
309
}
310
311
fn take_slice(&self, indices: &[IdxSize]) -> PolarsResult<Series> {
312
Ok(self.0.take(indices)?.into_series())
313
}
314
315
unsafe fn take_slice_unchecked(&self, indices: &[IdxSize]) -> Series {
316
self.0.take_unchecked(indices).into_series()
317
}
318
319
fn deposit(&self, validity: &Bitmap) -> Series {
320
self.0.deposit(validity).into_series()
321
}
322
323
fn len(&self) -> usize {
324
self.0.len()
325
}
326
327
fn rechunk(&self) -> Series {
328
self.0.rechunk().into_owned().into_series()
329
}
330
331
fn new_from_index(&self, index: usize, length: usize) -> Series {
332
ChunkExpandAtIndex::new_from_index(&self.0, index, length).into_series()
333
}
334
335
fn cast(&self, dtype: &DataType, options: CastOptions) -> PolarsResult<Series> {
336
self.0.cast_with_options(dtype, options)
337
}
338
339
#[inline]
340
unsafe fn get_unchecked(&self, index: usize) -> AnyValue<'_> {
341
self.0.get_any_value_unchecked(index)
342
}
343
344
fn sort_with(&self, options: SortOptions) -> PolarsResult<Series> {
345
Ok(ChunkSort::sort_with(&self.0, options).into_series())
346
}
347
348
fn arg_sort(&self, options: SortOptions) -> IdxCa {
349
ChunkSort::arg_sort(&self.0, options)
350
}
351
352
fn null_count(&self) -> usize {
353
self.0.null_count()
354
}
355
356
fn has_nulls(&self) -> bool {
357
self.0.has_nulls()
358
}
359
360
#[cfg(feature = "algorithm_group_by")]
361
fn unique(&self) -> PolarsResult<Series> {
362
ChunkUnique::unique(&self.0).map(|ca| ca.into_series())
363
}
364
365
#[cfg(feature = "algorithm_group_by")]
366
fn n_unique(&self) -> PolarsResult<usize> {
367
ChunkUnique::n_unique(&self.0)
368
}
369
370
#[cfg(feature = "algorithm_group_by")]
371
fn arg_unique(&self) -> PolarsResult<IdxCa> {
372
ChunkUnique::arg_unique(&self.0)
373
}
374
375
fn unique_id(&self) -> PolarsResult<(IdxSize, Vec<IdxSize>)> {
376
ChunkUnique::unique_id(&self.0)
377
}
378
379
fn is_null(&self) -> BooleanChunked {
380
self.0.is_null()
381
}
382
383
fn is_not_null(&self) -> BooleanChunked {
384
self.0.is_not_null()
385
}
386
387
fn reverse(&self) -> Series {
388
ChunkReverse::reverse(&self.0).into_series()
389
}
390
391
fn as_single_ptr(&mut self) -> PolarsResult<usize> {
392
self.0.as_single_ptr()
393
}
394
395
fn shift(&self, periods: i64) -> Series {
396
ChunkShift::shift(&self.0, periods).into_series()
397
}
398
399
fn sum_reduce(&self) -> PolarsResult<Scalar> {
400
Ok(ChunkAggSeries::sum_reduce(&self.0))
401
}
402
fn max_reduce(&self) -> PolarsResult<Scalar> {
403
Ok(ChunkAggSeries::max_reduce(&self.0))
404
}
405
fn min_reduce(&self) -> PolarsResult<Scalar> {
406
Ok(ChunkAggSeries::min_reduce(&self.0))
407
}
408
fn mean_reduce(&self) -> PolarsResult<Scalar> {
409
Ok(Scalar::new(DataType::Float64, self.mean().into()))
410
}
411
fn median_reduce(&self) -> PolarsResult<Scalar> {
412
Ok(QuantileAggSeries::median_reduce(&self.0))
413
}
414
fn var_reduce(&self, ddof: u8) -> PolarsResult<Scalar> {
415
Ok(VarAggSeries::var_reduce(&self.0, ddof))
416
}
417
fn std_reduce(&self, ddof: u8) -> PolarsResult<Scalar> {
418
Ok(VarAggSeries::std_reduce(&self.0, ddof))
419
}
420
421
fn quantile_reduce(
422
&self,
423
quantile: f64,
424
method: QuantileMethod,
425
) -> PolarsResult<Scalar> {
426
QuantileAggSeries::quantile_reduce(&self.0, quantile, method)
427
}
428
429
fn quantiles_reduce(
430
&self,
431
quantiles: &[f64],
432
method: QuantileMethod,
433
) -> PolarsResult<Scalar> {
434
QuantileAggSeries::quantiles_reduce(&self.0, quantiles, method)
435
}
436
437
#[cfg(feature = "bitwise")]
438
fn and_reduce(&self) -> PolarsResult<Scalar> {
439
let dt = <$pdt as PolarsDataType>::get_static_dtype();
440
let av = self.0.and_reduce().map_or(AnyValue::Null, Into::into);
441
442
Ok(Scalar::new(dt, av))
443
}
444
445
#[cfg(feature = "bitwise")]
446
fn or_reduce(&self) -> PolarsResult<Scalar> {
447
let dt = <$pdt as PolarsDataType>::get_static_dtype();
448
let av = self.0.or_reduce().map_or(AnyValue::Null, Into::into);
449
450
Ok(Scalar::new(dt, av))
451
}
452
453
#[cfg(feature = "bitwise")]
454
fn xor_reduce(&self) -> PolarsResult<Scalar> {
455
let dt = <$pdt as PolarsDataType>::get_static_dtype();
456
let av = self.0.xor_reduce().map_or(AnyValue::Null, Into::into);
457
458
Ok(Scalar::new(dt, av))
459
}
460
461
#[cfg(feature = "approx_unique")]
462
fn approx_n_unique(&self) -> PolarsResult<IdxSize> {
463
Ok(ChunkApproxNUnique::approx_n_unique(&self.0))
464
}
465
466
fn clone_inner(&self) -> Arc<dyn SeriesTrait> {
467
Arc::new(SeriesWrap(Clone::clone(&self.0)))
468
}
469
470
fn find_validity_mismatch(&self, other: &Series, idxs: &mut Vec<IdxSize>) {
471
self.0.find_validity_mismatch(other, idxs)
472
}
473
474
#[cfg(feature = "checked_arithmetic")]
475
fn checked_div(&self, rhs: &Series) -> PolarsResult<Series> {
476
self.0.checked_div(rhs)
477
}
478
479
fn as_any(&self) -> &dyn Any {
480
&self.0
481
}
482
483
fn as_any_mut(&mut self) -> &mut dyn Any {
484
&mut self.0
485
}
486
487
fn as_phys_any(&self) -> &dyn Any {
488
&self.0
489
}
490
491
fn as_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
492
self as _
493
}
494
}
495
};
496
}
497
498
#[cfg(feature = "dtype-u8")]
499
impl_dyn_series!(UInt8Chunked, UInt8Type);
500
#[cfg(feature = "dtype-u16")]
501
impl_dyn_series!(UInt16Chunked, UInt16Type);
502
impl_dyn_series!(UInt32Chunked, UInt32Type);
503
impl_dyn_series!(UInt64Chunked, UInt64Type);
504
#[cfg(feature = "dtype-u128")]
505
impl_dyn_series!(UInt128Chunked, UInt128Type);
506
#[cfg(feature = "dtype-i8")]
507
impl_dyn_series!(Int8Chunked, Int8Type);
508
#[cfg(feature = "dtype-i16")]
509
impl_dyn_series!(Int16Chunked, Int16Type);
510
impl_dyn_series!(Int32Chunked, Int32Type);
511
impl_dyn_series!(Int64Chunked, Int64Type);
512
#[cfg(feature = "dtype-i128")]
513
impl_dyn_series!(Int128Chunked, Int128Type);
514
515
impl<T: PolarsNumericType> private::PrivateSeriesNumeric for SeriesWrap<ChunkedArray<T>> {
516
fn bit_repr(&self) -> Option<BitRepr> {
517
Some(self.0.to_bit_repr())
518
}
519
}
520
521
impl private::PrivateSeriesNumeric for SeriesWrap<StringChunked> {
522
fn bit_repr(&self) -> Option<BitRepr> {
523
None
524
}
525
}
526
impl private::PrivateSeriesNumeric for SeriesWrap<BinaryChunked> {
527
fn bit_repr(&self) -> Option<BitRepr> {
528
None
529
}
530
}
531
impl private::PrivateSeriesNumeric for SeriesWrap<BinaryOffsetChunked> {
532
fn bit_repr(&self) -> Option<BitRepr> {
533
None
534
}
535
}
536
impl private::PrivateSeriesNumeric for SeriesWrap<ListChunked> {
537
fn bit_repr(&self) -> Option<BitRepr> {
538
None
539
}
540
}
541
#[cfg(feature = "dtype-array")]
542
impl private::PrivateSeriesNumeric for SeriesWrap<ArrayChunked> {
543
fn bit_repr(&self) -> Option<BitRepr> {
544
None
545
}
546
}
547
impl private::PrivateSeriesNumeric for SeriesWrap<BooleanChunked> {
548
fn bit_repr(&self) -> Option<BitRepr> {
549
let repr = self
550
.0
551
.cast_with_options(&DataType::UInt32, CastOptions::NonStrict)
552
.unwrap()
553
.u32()
554
.unwrap()
555
.clone();
556
557
Some(BitRepr::U32(repr))
558
}
559
}
560
561