@@ -1100,6 +1100,7 @@ impl LazyFrame {
11001100 logical_plan : self . logical_plan ,
11011101 opt_state,
11021102 keys,
1103+ predicates : vec ! [ ] ,
11031104 maintain_order : false ,
11041105 dynamic_options : None ,
11051106 rolling_options : None ,
@@ -1112,6 +1113,7 @@ impl LazyFrame {
11121113 logical_plan : self . logical_plan ,
11131114 opt_state,
11141115 keys,
1116+ predicates : vec ! [ ] ,
11151117 maintain_order : false ,
11161118 }
11171119 }
@@ -1147,6 +1149,7 @@ impl LazyFrame {
11471149 LazyGroupBy {
11481150 logical_plan : self . logical_plan ,
11491151 opt_state,
1152+ predicates : vec ! [ ] ,
11501153 keys : group_by. as_ref ( ) . to_vec ( ) ,
11511154 maintain_order : true ,
11521155 dynamic_options : None ,
@@ -1192,6 +1195,7 @@ impl LazyFrame {
11921195 LazyGroupBy {
11931196 logical_plan : self . logical_plan ,
11941197 opt_state,
1198+ predicates : vec ! [ ] ,
11951199 keys : group_by. as_ref ( ) . to_vec ( ) ,
11961200 maintain_order : true ,
11971201 dynamic_options : Some ( options) ,
@@ -1214,6 +1218,7 @@ impl LazyFrame {
12141218 logical_plan : self . logical_plan ,
12151219 opt_state,
12161220 keys,
1221+ predicates : vec ! [ ] ,
12171222 maintain_order : true ,
12181223 dynamic_options : None ,
12191224 rolling_options : None ,
@@ -1226,6 +1231,7 @@ impl LazyFrame {
12261231 logical_plan : self . logical_plan ,
12271232 opt_state,
12281233 keys,
1234+ predicates : vec ! [ ] ,
12291235 maintain_order : true ,
12301236 }
12311237 }
@@ -1975,6 +1981,7 @@ pub struct LazyGroupBy {
19751981 pub logical_plan : DslPlan ,
19761982 opt_state : OptFlags ,
19771983 keys : Vec < Expr > ,
1984+ predicates : Vec < Expr > ,
19781985 maintain_order : bool ,
19791986 #[ cfg( feature = "dynamic_group_by" ) ]
19801987 dynamic_options : Option < DynamicGroupOptions > ,
@@ -1993,6 +2000,31 @@ impl From<LazyGroupBy> for LazyFrame {
19932000}
19942001
19952002impl LazyGroupBy {
2003+ /// Filter groups with a predicate after aggregation.
2004+ ///
2005+ /// Similarly to the [LazyGroupBy::agg] method, the predicate must run an aggregation as it
2006+ /// is evaluated on the groups.
2007+ /// This method can be chained in which case all predicates must evaluate to `true` for a
2008+ /// group to be kept.
2009+ ///
2010+ /// # Example
2011+ ///
2012+ /// ```rust
2013+ /// use polars_core::prelude::*;
2014+ /// use polars_lazy::prelude::*;
2015+ ///
2016+ /// fn example(df: DataFrame) -> LazyFrame {
2017+ /// df.lazy()
2018+ /// .group_by_stable([col("date")])
2019+ /// .having(col("rain").sum().gt(lit(10)))
2020+ /// .agg([col("rain").min().alias("min_rain")])
2021+ /// }
2022+ /// ```
2023+ pub fn having ( mut self , predicate : Expr ) -> Self {
2024+ self . predicates . push ( predicate) ;
2025+ self
2026+ }
2027+
19962028 /// Group by and aggregate.
19972029 ///
19982030 /// Select a column with [col] and choose an aggregation.
@@ -2019,6 +2051,7 @@ impl LazyGroupBy {
20192051 let lp = DslBuilder :: from ( self . logical_plan )
20202052 . group_by (
20212053 self . keys ,
2054+ self . predicates ,
20222055 aggs,
20232056 None ,
20242057 self . maintain_order ,
@@ -2029,7 +2062,7 @@ impl LazyGroupBy {
20292062
20302063 #[ cfg( not( feature = "dynamic_group_by" ) ) ]
20312064 let lp = DslBuilder :: from ( self . logical_plan )
2032- . group_by ( self . keys , aggs, None , self . maintain_order )
2065+ . group_by ( self . keys , self . predicates , aggs, None , self . maintain_order )
20332066 . build ( ) ;
20342067 LazyFrame :: from_logical_plan ( lp, self . opt_state )
20352068 }
@@ -2075,6 +2108,10 @@ impl LazyGroupBy {
20752108 /// **It is not recommended that you use this as materializing the DataFrame is very
20762109 /// expensive.**
20772110 pub fn apply ( self , f : PlanCallback < DataFrame , DataFrame > , schema : SchemaRef ) -> LazyFrame {
2111+ if !self . predicates . is_empty ( ) {
2112+ panic ! ( "not yet implemented: `apply` cannot be used with `having` predicates" ) ;
2113+ }
2114+
20782115 #[ cfg( feature = "dynamic_group_by" ) ]
20792116 let options = GroupbyOptions {
20802117 dynamic : self . dynamic_options ,
@@ -2088,6 +2125,7 @@ impl LazyGroupBy {
20882125 let lp = DslPlan :: GroupBy {
20892126 input : Arc :: new ( self . logical_plan ) ,
20902127 keys : self . keys ,
2128+ predicates : vec ! [ ] ,
20912129 aggs : vec ! [ ] ,
20922130 apply : Some ( ( f, schema) ) ,
20932131 maintain_order : self . maintain_order ,
0 commit comments