Path: blob/main/crates/polars-ops/src/chunked_array/array/sum_mean.rs
6939 views
use arrow::array::{Array, PrimitiveArray};1use arrow::bitmap::Bitmap;2use arrow::legacy::utils::CustomIterTools;3use arrow::types::NativeType;4use num_traits::{NumCast, ToPrimitive};5use polars_core::prelude::*;67use crate::chunked_array::sum::sum_slice;89fn dispatch_sum<T, S>(arr: &dyn Array, width: usize, validity: Option<&Bitmap>) -> ArrayRef10where11T: NativeType + ToPrimitive,12S: NativeType + NumCast + std::iter::Sum,13{14let values = arr.as_any().downcast_ref::<PrimitiveArray<T>>().unwrap();15let values = values.values().as_slice();1617let summed: Vec<_> = (0..values.len())18.step_by(width)19.map(|start| {20let slice = unsafe { values.get_unchecked(start..start + width) };21sum_slice::<T, S>(slice)22})23.collect_trusted();2425Box::new(PrimitiveArray::from_data_default(26summed.into(),27validity.cloned(),28)) as ArrayRef29}3031pub(super) fn sum_array_numerical(ca: &ArrayChunked, inner_type: &DataType) -> Series {32let width = ca.width();33use DataType::*;34let chunks = ca35.downcast_iter()36.map(|arr| {37let values = arr.values().as_ref();3839match inner_type {40Int8 => dispatch_sum::<i8, i64>(values, width, arr.validity()),41Int16 => dispatch_sum::<i16, i64>(values, width, arr.validity()),42Int32 => dispatch_sum::<i32, i32>(values, width, arr.validity()),43Int64 => dispatch_sum::<i64, i64>(values, width, arr.validity()),44Int128 => dispatch_sum::<i128, i128>(values, width, arr.validity()),45UInt8 => dispatch_sum::<u8, i64>(values, width, arr.validity()),46UInt16 => dispatch_sum::<u16, i64>(values, width, arr.validity()),47UInt32 => dispatch_sum::<u32, u32>(values, width, arr.validity()),48UInt64 => dispatch_sum::<u64, u64>(values, width, arr.validity()),49Float32 => dispatch_sum::<f32, f32>(values, width, arr.validity()),50Float64 => dispatch_sum::<f64, f64>(values, width, arr.validity()),51_ => unimplemented!(),52}53})54.collect::<Vec<_>>();5556Series::try_from((ca.name().clone(), chunks)).unwrap()57}5859pub(super) fn sum_with_nulls(ca: &ArrayChunked, inner_dtype: &DataType) -> PolarsResult<Series> {60use DataType::*;61// TODO: add fast path for smaller ints?62let mut out = {63match inner_dtype {64Boolean => {65let out: IdxCa = ca66.amortized_iter()67.map(|s| s.and_then(|s| s.as_ref().sum().ok()))68.collect();69out.into_series()70},71UInt32 => {72let out: UInt32Chunked = ca73.amortized_iter()74.map(|s| s.and_then(|s| s.as_ref().sum().ok()))75.collect();76out.into_series()77},78UInt64 => {79let out: UInt64Chunked = ca80.amortized_iter()81.map(|s| s.and_then(|s| s.as_ref().sum().ok()))82.collect();83out.into_series()84},85Int32 => {86let out: Int32Chunked = ca87.amortized_iter()88.map(|s| s.and_then(|s| s.as_ref().sum().ok()))89.collect();90out.into_series()91},92Int64 => {93let out: Int64Chunked = ca94.amortized_iter()95.map(|s| s.and_then(|s| s.as_ref().sum().ok()))96.collect();97out.into_series()98},99#[cfg(feature = "dtype-i128")]100Int128 => {101let out: Int128Chunked = ca102.amortized_iter()103.map(|s| s.and_then(|s| s.as_ref().sum().ok()))104.collect();105out.into_series()106},107Float32 => {108let out: Float32Chunked = ca109.amortized_iter()110.map(|s| s.and_then(|s| s.as_ref().sum().ok()))111.collect();112out.into_series()113},114Float64 => {115let out: Float64Chunked = ca116.amortized_iter()117.map(|s| s.and_then(|s| s.as_ref().sum().ok()))118.collect();119out.into_series()120},121_ => {122polars_bail!(ComputeError: "summing array with dtype: {} not yet supported", ca.dtype())123},124}125};126out.rename(ca.name().clone());127Ok(out)128}129130131