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/count.rs
6939 views
1
use arrow::array::{Array, BooleanArray};
2
use arrow::bitmap::Bitmap;
3
use arrow::bitmap::utils::count_zeros;
4
use arrow::legacy::utils::CustomIterTools;
5
use polars_core::prelude::arity::unary_mut_with_options;
6
7
use super::*;
8
9
#[cfg(feature = "array_count")]
10
pub fn array_count_matches(ca: &ArrayChunked, value: AnyValue) -> PolarsResult<Series> {
11
let value = Series::new(PlSmallStr::EMPTY, [value]);
12
13
let ca = ca.apply_to_inner(&|s| {
14
ChunkCompareEq::<&Series>::equal_missing(&s, &value).map(|ca| ca.into_series())
15
})?;
16
let out = count_boolean_bits(&ca);
17
Ok(out.into_series())
18
}
19
20
pub(super) fn count_boolean_bits(ca: &ArrayChunked) -> IdxCa {
21
unary_mut_with_options(ca, |arr| {
22
let inner_arr = arr.values();
23
let mask = inner_arr.as_any().downcast_ref::<BooleanArray>().unwrap();
24
assert_eq!(mask.null_count(), 0);
25
let out = count_bits_set(mask.values(), arr.len(), arr.size());
26
IdxArr::from_data_default(out.into(), arr.validity().cloned())
27
})
28
}
29
30
fn count_bits_set(values: &Bitmap, len: usize, width: usize) -> Vec<IdxSize> {
31
// Fast path where all bits are either set or unset.
32
if values.unset_bits() == values.len() {
33
return vec![0 as IdxSize; len];
34
} else if values.unset_bits() == 0 {
35
return vec![width as IdxSize; len];
36
}
37
38
let (bits, bitmap_offset, _) = values.as_slice();
39
40
(0..len)
41
.map(|i| {
42
let set_ones = width - count_zeros(bits, bitmap_offset + i * width, width);
43
set_ones as IdxSize
44
})
45
.collect_trusted()
46
}
47
48