Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-ops/src/chunked_array/array/sum_mean.rs
8389 views
1
use arrow::array::{Array, PrimitiveArray};
2
use arrow::bitmap::Bitmap;
3
use arrow::legacy::utils::CustomIterTools;
4
use arrow::types::NativeType;
5
use num_traits::{NumCast, ToPrimitive};
6
use polars_core::prelude::*;
7
use polars_utils::float16::pf16;
8
9
use crate::chunked_array::sum::sum_slice;
10
11
fn dispatch_sum<T, S>(arr: &dyn Array, width: usize, validity: Option<&Bitmap>) -> ArrayRef
12
where
13
T: NativeType + ToPrimitive,
14
S: NativeType + NumCast + std::iter::Sum,
15
{
16
let values = arr.as_any().downcast_ref::<PrimitiveArray<T>>().unwrap();
17
let values = values.values().as_slice();
18
19
let summed: Vec<_> = (0..values.len())
20
.step_by(width)
21
.map(|start| {
22
let slice = unsafe { values.get_unchecked(start..start + width) };
23
sum_slice::<T, S>(slice)
24
})
25
.collect_trusted();
26
27
Box::new(PrimitiveArray::from_data_default(
28
summed.into(),
29
validity.cloned(),
30
)) as ArrayRef
31
}
32
33
pub(super) fn sum_array_numerical(ca: &ArrayChunked, inner_type: &DataType) -> Series {
34
let width = ca.width();
35
use DataType::*;
36
let chunks = ca
37
.downcast_iter()
38
.map(|arr| {
39
let values = arr.values().as_ref();
40
41
match inner_type {
42
Int8 => dispatch_sum::<i8, i64>(values, width, arr.validity()),
43
Int16 => dispatch_sum::<i16, i64>(values, width, arr.validity()),
44
Int32 => dispatch_sum::<i32, i32>(values, width, arr.validity()),
45
Int64 => dispatch_sum::<i64, i64>(values, width, arr.validity()),
46
Int128 => dispatch_sum::<i128, i128>(values, width, arr.validity()),
47
UInt8 => dispatch_sum::<u8, i64>(values, width, arr.validity()),
48
UInt16 => dispatch_sum::<u16, i64>(values, width, arr.validity()),
49
UInt32 => dispatch_sum::<u32, u32>(values, width, arr.validity()),
50
UInt64 => dispatch_sum::<u64, u64>(values, width, arr.validity()),
51
UInt128 => dispatch_sum::<u128, u128>(values, width, arr.validity()),
52
Float16 => dispatch_sum::<pf16, pf16>(values, width, arr.validity()),
53
Float32 => dispatch_sum::<f32, f32>(values, width, arr.validity()),
54
Float64 => dispatch_sum::<f64, f64>(values, width, arr.validity()),
55
_ => unimplemented!(),
56
}
57
})
58
.collect::<Vec<_>>();
59
60
Series::try_from((ca.name().clone(), chunks)).unwrap()
61
}
62
63
pub(super) fn sum_with_nulls(ca: &ArrayChunked, inner_dtype: &DataType) -> PolarsResult<Series> {
64
use DataType::*;
65
let mut out = {
66
match inner_dtype {
67
Boolean => {
68
let out: IdxCa = ca
69
.amortized_iter()
70
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
71
.collect();
72
out.into_series()
73
},
74
UInt8 => {
75
let out: Int64Chunked = ca
76
.amortized_iter()
77
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
78
.collect();
79
out.into_series()
80
},
81
UInt16 => {
82
let out: Int64Chunked = ca
83
.amortized_iter()
84
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
85
.collect();
86
out.into_series()
87
},
88
UInt32 => {
89
let out: UInt32Chunked = ca
90
.amortized_iter()
91
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
92
.collect();
93
out.into_series()
94
},
95
UInt64 => {
96
let out: UInt64Chunked = ca
97
.amortized_iter()
98
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
99
.collect();
100
out.into_series()
101
},
102
#[cfg(feature = "dtype-u128")]
103
UInt128 => {
104
let out: UInt128Chunked = ca
105
.amortized_iter()
106
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
107
.collect();
108
out.into_series()
109
},
110
Int8 => {
111
let out: Int64Chunked = ca
112
.amortized_iter()
113
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
114
.collect();
115
out.into_series()
116
},
117
Int16 => {
118
let out: Int64Chunked = ca
119
.amortized_iter()
120
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
121
.collect();
122
out.into_series()
123
},
124
Int32 => {
125
let out: Int32Chunked = ca
126
.amortized_iter()
127
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
128
.collect();
129
out.into_series()
130
},
131
Int64 => {
132
let out: Int64Chunked = ca
133
.amortized_iter()
134
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
135
.collect();
136
out.into_series()
137
},
138
#[cfg(feature = "dtype-i128")]
139
Int128 => {
140
let out: Int128Chunked = ca
141
.amortized_iter()
142
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
143
.collect();
144
out.into_series()
145
},
146
#[cfg(feature = "dtype-f16")]
147
Float16 => {
148
let out: Float16Chunked = ca
149
.amortized_iter()
150
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
151
.collect();
152
out.into_series()
153
},
154
Float32 => {
155
let out: Float32Chunked = ca
156
.amortized_iter()
157
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
158
.collect();
159
out.into_series()
160
},
161
Float64 => {
162
let out: Float64Chunked = ca
163
.amortized_iter()
164
.map(|s| s.and_then(|s| s.as_ref().sum().ok()))
165
.collect();
166
out.into_series()
167
},
168
_ => {
169
polars_bail!(ComputeError: "summing array with dtype: {} not yet supported", ca.dtype())
170
},
171
}
172
};
173
out.rename(ca.name().clone());
174
Ok(out)
175
}
176
177