Path: blob/main/crates/polars-core/src/series/implementations/array.rs
8393 views
use std::any::Any;1use std::borrow::Cow;23use arrow::bitmap::Bitmap;45use self::compare_inner::{TotalEqInner, TotalOrdInner};6use self::sort::arg_sort_row_fmt;7use super::{IsSorted, StatisticsFlags, private};8use crate::POOL;9use crate::chunked_array::AsSinglePtr;10use crate::chunked_array::cast::CastOptions;11use crate::chunked_array::comparison::*;12#[cfg(feature = "algorithm_group_by")]13use crate::frame::group_by::*;14use crate::prelude::row_encode::{_get_rows_encoded_ca_unordered, encode_rows_unordered};15use crate::prelude::*;16use crate::series::implementations::SeriesWrap;1718impl private::PrivateSeries for SeriesWrap<ArrayChunked> {19fn compute_len(&mut self) {20self.0.compute_len()21}22fn _field(&self) -> Cow<'_, Field> {23Cow::Borrowed(self.0.ref_field())24}25fn _dtype(&self) -> &DataType {26self.0.ref_field().dtype()27}2829fn _get_flags(&self) -> StatisticsFlags {30self.0.get_flags()31}3233fn _set_flags(&mut self, flags: StatisticsFlags) {34self.0.set_flags(flags)35}3637unsafe fn equal_element(&self, idx_self: usize, idx_other: usize, other: &Series) -> bool {38self.0.equal_element(idx_self, idx_other, other)39}4041fn vec_hash(42&self,43build_hasher: PlSeedableRandomStateQuality,44buf: &mut Vec<u64>,45) -> PolarsResult<()> {46_get_rows_encoded_ca_unordered(PlSmallStr::EMPTY, &[self.0.clone().into_column()])?47.vec_hash(build_hasher, buf)48}4950fn vec_hash_combine(51&self,52build_hasher: PlSeedableRandomStateQuality,53hashes: &mut [u64],54) -> PolarsResult<()> {55_get_rows_encoded_ca_unordered(PlSmallStr::EMPTY, &[self.0.clone().into_column()])?56.vec_hash_combine(build_hasher, hashes)57}5859#[cfg(feature = "zip_with")]60fn zip_with_same_type(&self, mask: &BooleanChunked, other: &Series) -> PolarsResult<Series> {61ChunkZip::zip_with(&self.0, mask, other.as_ref().as_ref()).map(|ca| ca.into_series())62}6364#[cfg(feature = "algorithm_group_by")]65unsafe fn agg_list(&self, groups: &GroupsType) -> Series {66self.0.agg_list(groups)67}6869#[cfg(feature = "algorithm_group_by")]70fn group_tuples(&self, multithreaded: bool, sorted: bool) -> PolarsResult<GroupsType> {71IntoGroupsType::group_tuples(&self.0, multithreaded, sorted)72}7374fn add_to(&self, rhs: &Series) -> PolarsResult<Series> {75self.0.add_to(rhs)76}7778fn subtract(&self, rhs: &Series) -> PolarsResult<Series> {79self.0.subtract(rhs)80}8182fn multiply(&self, rhs: &Series) -> PolarsResult<Series> {83self.0.multiply(rhs)84}85fn divide(&self, rhs: &Series) -> PolarsResult<Series> {86self.0.divide(rhs)87}88fn remainder(&self, rhs: &Series) -> PolarsResult<Series> {89self.0.remainder(rhs)90}9192fn into_total_eq_inner<'a>(&'a self) -> Box<dyn TotalEqInner + 'a> {93invalid_operation_panic!(into_total_eq_inner, self)94}95fn into_total_ord_inner<'a>(&'a self) -> Box<dyn TotalOrdInner + 'a> {96invalid_operation_panic!(into_total_ord_inner, self)97}98}99100impl SeriesTrait for SeriesWrap<ArrayChunked> {101fn rename(&mut self, name: PlSmallStr) {102self.0.rename(name);103}104105fn chunk_lengths(&self) -> ChunkLenIter<'_> {106self.0.chunk_lengths()107}108fn name(&self) -> &PlSmallStr {109self.0.name()110}111112fn chunks(&self) -> &Vec<ArrayRef> {113self.0.chunks()114}115unsafe fn chunks_mut(&mut self) -> &mut Vec<ArrayRef> {116self.0.chunks_mut()117}118fn shrink_to_fit(&mut self) {119self.0.shrink_to_fit()120}121122fn arg_sort(&self, options: SortOptions) -> IdxCa {123let slf = (*self).clone();124let slf = slf.into_column();125arg_sort_row_fmt(126&[slf],127options.descending,128options.nulls_last,129options.multithreaded,130)131.unwrap()132}133134fn sort_with(&self, options: SortOptions) -> PolarsResult<Series> {135let idxs = self.arg_sort(options);136let mut result = unsafe { self.take_unchecked(&idxs) };137result.set_sorted_flag(if options.descending {138IsSorted::Descending139} else {140IsSorted::Ascending141});142Ok(result)143}144145fn slice(&self, offset: i64, length: usize) -> Series {146self.0.slice(offset, length).into_series()147}148149fn split_at(&self, offset: i64) -> (Series, Series) {150let (a, b) = self.0.split_at(offset);151(a.into_series(), b.into_series())152}153154fn append(&mut self, other: &Series) -> PolarsResult<()> {155polars_ensure!(self.0.dtype() == other.dtype(), append);156let other = other.array()?;157self.0.append(other)158}159fn append_owned(&mut self, other: Series) -> PolarsResult<()> {160polars_ensure!(self.0.dtype() == other.dtype(), append);161self.0.append_owned(other.take_inner())162}163164fn extend(&mut self, other: &Series) -> PolarsResult<()> {165polars_ensure!(self.0.dtype() == other.dtype(), extend);166self.0.extend(other.as_ref().as_ref())167}168169fn filter(&self, filter: &BooleanChunked) -> PolarsResult<Series> {170ChunkFilter::filter(&self.0, filter).map(|ca| ca.into_series())171}172173fn take(&self, indices: &IdxCa) -> PolarsResult<Series> {174Ok(self.0.take(indices)?.into_series())175}176177unsafe fn take_unchecked(&self, indices: &IdxCa) -> Series {178self.0.take_unchecked(indices).into_series()179}180181fn take_slice(&self, indices: &[IdxSize]) -> PolarsResult<Series> {182Ok(self.0.take(indices)?.into_series())183}184185unsafe fn take_slice_unchecked(&self, indices: &[IdxSize]) -> Series {186self.0.take_unchecked(indices).into_series()187}188189fn deposit(&self, validity: &Bitmap) -> Series {190self.0.deposit(validity).into_series()191}192193fn len(&self) -> usize {194self.0.len()195}196197fn rechunk(&self) -> Series {198self.0.rechunk().into_owned().into_series()199}200201fn new_from_index(&self, index: usize, length: usize) -> Series {202ChunkExpandAtIndex::new_from_index(&self.0, index, length).into_series()203}204205fn trim_lists_to_normalized_offsets(&self) -> Option<Series> {206self.0207.trim_lists_to_normalized_offsets()208.map(IntoSeries::into_series)209}210211fn propagate_nulls(&self) -> Option<Series> {212self.0.propagate_nulls().map(IntoSeries::into_series)213}214215fn cast(&self, dtype: &DataType, options: CastOptions) -> PolarsResult<Series> {216self.0.cast_with_options(dtype, options)217}218219#[inline]220unsafe fn get_unchecked(&self, index: usize) -> AnyValue<'_> {221self.0.get_any_value_unchecked(index)222}223224fn null_count(&self) -> usize {225self.0.null_count()226}227228fn has_nulls(&self) -> bool {229self.0.has_nulls()230}231232#[cfg(feature = "algorithm_group_by")]233fn unique(&self) -> PolarsResult<Series> {234// this can be called in aggregation, so this fast path can be worth a lot235if self.len() < 2 {236return Ok(self.0.clone().into_series());237}238let main_thread = POOL.current_thread_index().is_none();239let groups = self.group_tuples(main_thread, false);240// SAFETY:241// groups are in bounds242Ok(unsafe { self.0.clone().into_series().agg_first(&groups?) })243}244245#[cfg(feature = "algorithm_group_by")]246fn n_unique(&self) -> PolarsResult<usize> {247// this can be called in aggregation, so this fast path can be worth a lot248match self.len() {2490 => Ok(0),2501 => Ok(1),251_ => {252let main_thread = POOL.current_thread_index().is_none();253let groups = self.group_tuples(main_thread, false)?;254Ok(groups.len())255},256}257}258259#[cfg(feature = "algorithm_group_by")]260fn arg_unique(&self) -> PolarsResult<IdxCa> {261// this can be called in aggregation, so this fast path can be worth a lot262if self.len() == 1 {263return Ok(IdxCa::new_vec(self.name().clone(), vec![0 as IdxSize]));264}265let main_thread = POOL.current_thread_index().is_none();266// arg_unique requires a stable order267let groups = self.group_tuples(main_thread, true)?;268let first = groups.take_group_firsts();269Ok(IdxCa::from_vec(self.name().clone(), first))270}271272fn unique_id(&self) -> PolarsResult<(IdxSize, Vec<IdxSize>)> {273let ca = encode_rows_unordered(&[self.0.clone().into_column()])?;274ChunkUnique::unique_id(&ca)275}276277fn is_null(&self) -> BooleanChunked {278self.0.is_null()279}280281fn is_not_null(&self) -> BooleanChunked {282self.0.is_not_null()283}284285fn reverse(&self) -> Series {286ChunkReverse::reverse(&self.0).into_series()287}288289fn as_single_ptr(&mut self) -> PolarsResult<usize> {290self.0.as_single_ptr()291}292293fn shift(&self, periods: i64) -> Series {294ChunkShift::shift(&self.0, periods).into_series()295}296297fn clone_inner(&self) -> Arc<dyn SeriesTrait> {298Arc::new(SeriesWrap(Clone::clone(&self.0)))299}300301fn find_validity_mismatch(&self, other: &Series, idxs: &mut Vec<IdxSize>) {302self.0.find_validity_mismatch(other, idxs)303}304305fn as_any(&self) -> &dyn Any {306&self.0307}308309fn as_any_mut(&mut self) -> &mut dyn Any {310&mut self.0311}312313fn as_phys_any(&self) -> &dyn Any {314&self.0315}316317fn as_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {318self as _319}320}321322323