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