Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-ops/src/series/ops/unique.rs
6939 views
1
use std::hash::Hash;
2
3
use polars_core::hashing::_HASHMAP_INIT_SIZE;
4
use polars_core::prelude::*;
5
use polars_core::utils::NoNull;
6
use polars_core::with_match_physical_numeric_polars_type;
7
use polars_utils::total_ord::{ToTotalOrd, TotalEq, TotalHash};
8
9
fn unique_counts_helper<I, J>(items: I) -> IdxCa
10
where
11
I: Iterator<Item = J>,
12
J: TotalHash + TotalEq + ToTotalOrd,
13
<J as ToTotalOrd>::TotalOrdItem: Hash + Eq,
14
{
15
let mut map = PlIndexMap::with_capacity_and_hasher(_HASHMAP_INIT_SIZE, Default::default());
16
for item in items {
17
let item = item.to_total_ord();
18
map.entry(item)
19
.and_modify(|cnt| {
20
*cnt += 1;
21
})
22
.or_insert(1 as IdxSize);
23
}
24
let out: NoNull<IdxCa> = map.into_values().collect();
25
out.into_inner()
26
}
27
28
/// Returns a count of the unique values in the order of appearance.
29
pub fn unique_counts(s: &Series) -> PolarsResult<Series> {
30
if s.dtype().to_physical().is_primitive_numeric() {
31
let s_physical = s.to_physical_repr();
32
33
with_match_physical_numeric_polars_type!(s_physical.dtype(), |$T| {
34
let ca: &ChunkedArray<$T> = s_physical.as_ref().as_ref().as_ref();
35
Ok(unique_counts_helper(ca.iter()).into_series())
36
})
37
} else {
38
match s.dtype() {
39
DataType::String => {
40
Ok(unique_counts_helper(s.str().unwrap().into_iter()).into_series())
41
},
42
DataType::Null => {
43
let ca = if s.is_empty() {
44
IdxCa::new(s.name().clone(), [] as [IdxSize; 0])
45
} else {
46
IdxCa::new(s.name().clone(), [s.len() as IdxSize])
47
};
48
Ok(ca.into_series())
49
},
50
dt => {
51
polars_bail!(opq = unique_counts, dt)
52
},
53
}
54
}
55
}
56
57