Path: blob/main/crates/polars-ops/src/chunked_array/array/count.rs
6939 views
use arrow::array::{Array, BooleanArray};1use arrow::bitmap::Bitmap;2use arrow::bitmap::utils::count_zeros;3use arrow::legacy::utils::CustomIterTools;4use polars_core::prelude::arity::unary_mut_with_options;56use super::*;78#[cfg(feature = "array_count")]9pub fn array_count_matches(ca: &ArrayChunked, value: AnyValue) -> PolarsResult<Series> {10let value = Series::new(PlSmallStr::EMPTY, [value]);1112let ca = ca.apply_to_inner(&|s| {13ChunkCompareEq::<&Series>::equal_missing(&s, &value).map(|ca| ca.into_series())14})?;15let out = count_boolean_bits(&ca);16Ok(out.into_series())17}1819pub(super) fn count_boolean_bits(ca: &ArrayChunked) -> IdxCa {20unary_mut_with_options(ca, |arr| {21let inner_arr = arr.values();22let mask = inner_arr.as_any().downcast_ref::<BooleanArray>().unwrap();23assert_eq!(mask.null_count(), 0);24let out = count_bits_set(mask.values(), arr.len(), arr.size());25IdxArr::from_data_default(out.into(), arr.validity().cloned())26})27}2829fn count_bits_set(values: &Bitmap, len: usize, width: usize) -> Vec<IdxSize> {30// Fast path where all bits are either set or unset.31if values.unset_bits() == values.len() {32return vec![0 as IdxSize; len];33} else if values.unset_bits() == 0 {34return vec![width as IdxSize; len];35}3637let (bits, bitmap_offset, _) = values.as_slice();3839(0..len)40.map(|i| {41let set_ones = width - count_zeros(bits, bitmap_offset + i * width, width);42set_ones as IdxSize43})44.collect_trusted()45}464748