Path: blob/main/crates/polars-expr/src/expressions/count.rs
6940 views
use std::borrow::Cow;12use polars_core::prelude::*;3use polars_plan::constants::LEN;45use super::*;6use crate::expressions::{AggregationContext, PartitionedAggregation, PhysicalExpr};78pub struct CountExpr {9expr: Expr,10}1112impl CountExpr {13pub(crate) fn new() -> Self {14Self { expr: Expr::Len }15}16}1718impl PhysicalExpr for CountExpr {19fn as_expression(&self) -> Option<&Expr> {20Some(&self.expr)21}2223fn evaluate(&self, df: &DataFrame, _state: &ExecutionState) -> PolarsResult<Column> {24Ok(Column::new_scalar(25PlSmallStr::from_static(LEN),26Scalar::from(df.height() as IdxSize),271,28))29}3031fn evaluate_on_groups<'a>(32&self,33_df: &DataFrame,34groups: &'a GroupPositions,35_state: &ExecutionState,36) -> PolarsResult<AggregationContext<'a>> {37let ca = groups.group_count().with_name(PlSmallStr::from_static(LEN));38let c = ca.into_column();39Ok(AggregationContext::new(c, Cow::Borrowed(groups), true))40}4142fn to_field(&self, _input_schema: &Schema) -> PolarsResult<Field> {43Ok(Field::new(PlSmallStr::from_static(LEN), IDX_DTYPE))44}4546fn as_partitioned_aggregator(&self) -> Option<&dyn PartitionedAggregation> {47Some(self)48}4950fn is_scalar(&self) -> bool {51true52}53}5455impl PartitionedAggregation for CountExpr {56#[allow(clippy::ptr_arg)]57fn evaluate_partitioned(58&self,59df: &DataFrame,60groups: &GroupPositions,61state: &ExecutionState,62) -> PolarsResult<Column> {63self.evaluate_on_groups(df, groups, state)64.map(|mut ac| ac.aggregated().into_column())65}6667/// Called to merge all the partitioned results in a final aggregate.68#[allow(clippy::ptr_arg)]69fn finalize(70&self,71partitioned: Column,72groups: &GroupPositions,73_state: &ExecutionState,74) -> PolarsResult<Column> {75// SAFETY: groups are in bounds.76let agg = unsafe { partitioned.agg_sum(groups) };77Ok(agg.with_name(PlSmallStr::from_static(LEN)))78}79}808182