
    LpjL?                       % S SK Jr  S SKrS SKJr  S SKJr  S SKJr  S SK	J
r
JrJrJr  S SKJr  S SKJr  S S	KJr  S S
KJr  S SKJr  \
(       a?  S SKJrJrJrJrJr  S SK	Jr  S SKr S SK!J"r#  S SK$J%r%  S SK&J'r'J(r(  S SK)J*r*  S SK+J,r,  Sr-S\.S'   Sr/S\.S'   \S   r0S\.S'   \SSSSSSS S!S"S#S$S%S&S'S(S)S*S+S,\04   r1S\.S-'    S.r2S\.S/'    \r3S\.S0'    S S1S S2.r4S3\.S4'   \" S5S69S@S7 j5       r5 " S8 S95      r6 " S: S;\S<S=\14   5      r7SAS> jr8SBS? jr9g)C    )annotationsN)	lru_cache)chain)methodcaller)TYPE_CHECKINGAnyClassVarLiteral)EagerGroupBy)issue_warning)!evaluate_output_names_and_aliases)make_group_by_kwargs)is_pandas_like_dataframe)CallableIterableIteratorMappingSequence)	TypeAlias)DataFrameGroupBy)Unpack)NarwhalsAggregationScalarKwargs)PandasLikeDataFrame)PandasLikeExprz._NativeGroupBy[tuple[str, ...], Literal[True]]r   NativeGroupByz(Callable[[pd.DataFrame], pd.Series[Any]]NativeApply)covskewInefficientNativeAggregationanyallcountidxmaxidxminmaxmeanmedianminmodenthnuniqueprodquantilesemsizestdsumvarNativeAggregationz.Callable[[Any], pd.DataFrame | pd.Series[Any]]
_NativeAggNonStrHashable)firstlast	any_valuez,Mapping[NarwhalsAggregation, Literal[0, -1]]_REMAP_ORDERED_INDEX    )maxsizec                   U S:X  a
  [        U SS9$ U S:X  a   SU;   d   eSU;   d   e[        XS   US   S9$ U(       a  UR                  S5      S:X  a  [        U 5      $ [        U 40 UD6$ )	Nr,   F)dropnar.   interpolation)qr@   ddof   )r   get)namekwdss     Z/var/www/html/pdf-tiff/venv/lib/python3.13/site-packages/narwhals/_pandas_like/group_by.py_native_aggrH   E   s    yD//zT!!!$&&&D$4DDYZZ488F#q(D!!%%%    c                      \ rS rSr% SrS\S'   S\S'   S\S'   SS jrSS	 jrSS
 jrSS jr	SS jr
SS jrSS jrSS jrSS jr\SS j5       rSS jrSrg)AggExprR   a5  Wrapper storing the intermediate state per-`PandasLikeExpr`.

There's a lot of edge cases to handle, so aim to evaluate as little
as possible - and store anything that's needed twice.

Warning:
    While a `PandasLikeExpr` can be reused - this wrapper is valid **only**
    in a single `.agg(...)` operation.
r   exprzSequence[str]output_namesaliasesc                :    Xl         SU l        SU l        SU l        g )N  )rM   rN   rO   
_leaf_name)selfrM   s     rG   __init__AggExpr.__init__a   s    	57rI   c               |    UR                   nUR                  n[        U R                  X#5      u  U l        U l        U $ )zT**Mutating operation**.

Stores the results of `evaluate_output_names_and_aliases`.
)	compliantexcluder   rM   rN   rO   )rT   group_bydfrY   s       rG   with_expand_namesAggExpr.with_expand_namesg   s>    
 ""*KIIr+
'4< rI   c           
     
   UR                   nU R                  nU R                  5       (       a'  U R                  5       (       a  UR	                  5       nGOU R                  5       (       au  UR	                  5       nUR
                  R                  5       nUR                  U Vs/ s H,  ovR                  U5      R                  U5      R                  PM.     sn5      nGOZU R                  5       (       Ga.  UR
                  nUR                  U R                  5      n	U	R                  S5      =n
S:w  a  SU
 SUR                   S3n[!        U5      e[#        U5      nUR                  nUR$                  UR&                  pUR                  5       nUR                  U Vs/ s Hu  nUR(                  " / UQUP40 UD6R	                  5       R+                  SS9R-                  U5      R(                  " U40 UD6U   R/                  S5      R1                  5       PMw     sn5      nGOU R3                  5       (       d*  U R5                  5       (       d  U R7                  5       (       a  U R9                  5       " U/ UR$                  QUQ   5      nUR
                  R                  nUR;                  5       nUR=                  5       (       a!  US	:  a  UR?                  UR$                  S
S9  OTUR?                  UR$                  5      nO8[A        U5      S:X  a  US   O
[#        U5      nU R9                  5       " UU   5      n[C        U5      (       a  [#        U RD                  5      Ul#        U$ U RD                  S   Ul$        U$ s  snf s  snf )z8Evaluate the wrapped expression as a group_by operation.keepr!   z`Expr.mode(keep='z7')` is not implemented in group by context for backend z3

Hint: Use `nw.col(...).mode(keep='any')` instead.F)	ascendingrC      r   Tinplacer   )%_groupedrN   is_lenis_top_level_functionr0   rX   __narwhals_namespace___concat_by_indexfrom_nativealiasnativeis_mode_kwargsrM   rD   _implementationNotImplementedErrorlist_keys_group_by_kwargsgroupbysort_valuesreset_indexhead
sort_indexis_lastis_firstis_any_value
native_agg_backend_version	is_pandas	set_indexlenr   rO   columnsrE   )rT   rZ   groupednamesresultresult_singlensrE   rX   node_kwargsr_   msgcolsrl   keyskwargscolimplbackend_versionselects                       rG   _getitem_aggsAggExpr._getitem_aggss   s
   ##!!;;==T7799\\^F[[]]#LLNM##::<B((NSTed.44T:AAeTF \\^^ **I"**4995K#//E9'v .(889 :HH 
 *#..;D%%F#>>8+D+D& 113B((  $	  $ NN<T<3<:6:TV [5[1 [%W	 "	- &,	- .1	2
 T!WZ\"  $	F \\^^t}}$2C2C2E2E__&w/H/H%/H'IJF%%55D"335O~~Of$<   >))(..9!$UqU1Xd5kF__&wv7F#F++!$,,/FN  ,,q/FKa U*	s   #3M;A<N c                     U R                   S:H  $ )Nr   	leaf_namerT   s    rG   rf   AggExpr.is_len   s    ~~&&rI   c                     U R                   S:H  $ )Nr9   r   r   s    rG   ry   AggExpr.is_last       ~~''rI   c                     U R                   S:H  $ )Nr8   r   r   s    rG   rz   AggExpr.is_first   s    ~~((rI   c                     U R                   S:H  $ )Nr*   r   r   s    rG   rm   AggExpr.is_mode   r   rI   c                     U R                   S:H  $ )Nr:   r   r   s    rG   r{   AggExpr.is_any_value   s    ~~,,rI   c                t    [        [        U R                  R                  R	                  5       5      5      S:H  $ )NrC   )r   rq   rM   	_metadataop_nodes_reversedr   s    rG   rg   AggExpr.is_top_level_function   s*    4		++==?@AQFFrI   c                    U R                   =n(       a  U$ [        R                  U R                  5      U l         U R                   $ N)rS   PandasLikeGroupByrM   )rT   rE   s     rG   r   AggExpr.leaf_name   s6    ??"4"K+66tyyArI   c                ~   [         R                  U R                  5      n[        U R                  R
                  R                  5       5      nU R                  [        ;   aH  UR                  R                  S5      (       a  Sn[        U5      e[        S[        U R                     S9$ [        U40 UR                  D6$ )z@Return a partial `DataFrameGroupBy` method, missing only `self`.ignore_nullszd`Expr.any_value(ignore_nulls=True)` is not supported in a `group_by` context for pandas-like backendr+   )n)r   _remap_expr_namer   nextrM   r   r   r;   r   rD   rp   r   rH   )rT   native_name	last_noder   s       rG   r|   AggExpr.native_agg   s    '88H,,>>@A	>>11##N336  *#..)=dnn)MNN;;)*:*:;;rI   )rS   rO   rM   rN   N)rM   r   returnNone)rZ   r   r   rK   )rZ   r   r   zpd.DataFrame | pd.Series[Any])r   bool)r   zNarwhalsAggregation | Any)r   r5   )__name__
__module____qualname____firstlineno____doc____annotations__rU   r\   r   rf   ry   rz   rm   r{   rg   propertyr   r|   __static_attributes__rQ   rI   rG   rK   rK   R   sc     8
;z'()(-G  <rI   rK   c                  D   \ rS rSr% 0 SS_SS_SS_SS_SS_SS_SS_S	S	_S
S_SS_SS_SS_SS_SS_SS_SS_SS_rS\S'   S\S'    S\S'    S\S'    S\S'    \S)S j5       r        S*S  jrS+S! jr	      S,S" jr
    S-S# jr      S.S$ jrS/S% jrS0S& jrS'rg()1r      r2   r'   r(   r&   r)   r*   r1   r3   r   r0   n_uniquer,   r#   r.   r"   r!   r8   r+   r9   r:   z9ClassVar[Mapping[NarwhalsAggregation, NativeAggregation]]_REMAP_AGGStuple[str, ...]_original_columnsz	list[str]rr   _output_key_nameszMapping[str, bool]rs   c                    U R                   $ )z>Group keys to ignore when expanding multi-output aggregations.)_excluder   s    rG   rY   PandasLikeGroupBy.exclude   s     }}rI   c                 [        UR                  5      U l        X0l        U R	                  X5      u  U l        U l        U l        / U R                  QU R                  Q7U l        [        US9U l
        U R                  R                  U l        [        U R                  R                  R                   5      R#                  U R                  R                  5      (       a  U R                  R%                  SS9U l        g g )N)drop_null_keysT)drop)tupler   r   _drop_null_keys_parse_keys_compliant_framerr   r   r   r   rs   rX   rl   _nativesetindexr   intersectionrv   )rT   r[   r   r   s       rG   rU   PandasLikeGroupBy.__init__   s     "'rzz!2-DHDTDTE
Atz4+A *P4::)O8N8N)O 4N S ~~,,t||!!''(55dnn6L6LMM<<333>DL NrI   c                >   Sn/ nSnU H  nUR                  [        U5      R                  U 5      5        U R                  U5      (       d  Sn[	        UR
                  R                  5       5      nUR                  R                  SS5      =n(       d  M  U(       a  Xt:w  a  SU SU S3n[        U5      eUnM     U(       aW  U R                  R                  [        U5      SS	9R                  " U R                  R                  5       40 U R                   D6n	O?U R                  R                  " U R                  R                  5       40 U R                   D6n	Xl        U(       a  U(       a;  U R$                  R'                  5       n
U
R)                  U R+                  U5      5      nOU R$                  R-                  5       R/                  [        U	R0                  5      U R                  S
9nO@U R$                  R2                  R4                  (       a
  [7        5       eU R9                  X5      nU R$                  R:                  nUR=                  5       nUR?                  5       (       a  US:  a  URA                  SS9  OURA                  5       nU RC                  X5      $ )NTrQ   Forder_byz?Only one `order_by` can be specified in `group_by`. Found both z and .r8   )na_position)r   ra   rc   )"appendrK   r\   
_is_simpler   r   r   r   rD   rp   r   ru   rq   rt   rr   copyrs   re   rX   rh   ri   r   __native_namespace__	DataFramegroupsrl   emptyempty_results_error_apply_aggsro   r}   r~   rv   _select_results)rT   exprsall_aggs_are_simple	agg_exprsr   rM   md_current_order_byr   r   r   r   r   r   s                 rG   aggPandasLikeGroupBy.agg  s/   "#%	DWT]<<TBC??4((&+#dnn6689B$&IIMM*b$AA A 1 =[\d[eejk|j}}~C-c22,  %)\\%=%=XG &> &g&jjoo'&B+/+@+@&BG ll**4::??+<V@U@UVG^^::<,,T-?-?	-JK<<>HH($** I  ^^""((%''%%g5F~~--//1>>& 8t,'')F##F66rI   c          
        [         R                  " S U 5       5      nU R                  R                  USS9R                  " / U R
                  QUQ76 R                  [        [        U R
                  U R                  SS95      5      $ )zWResponsible for remapping temp column names back to original.

See `ParseKeysGroupBy`.
c              3  8   #    U  H  oR                   v   M     g 7fr   )rO   ).0es     rG   	<genexpr>4PandasLikeGroupBy._select_results.<locals>.<genexpr>L  s     'E9a		9s   F)validate_column_names)strict)
r   from_iterablerX   _with_nativesimple_selectrr   renamedictzipr   )rT   r[   r   	new_namess       rG   r   !PandasLikeGroupBy._select_resultsE  s{     '''E9'EE	NN''%'H] 4 JJ4)24VDTZZ)?)?NOP	
rI   c               N    U Vs/ s H  o"R                  U 5      PM     sn$ s  snf r   )r   )rT   r   r   s      rG   r   PandasLikeGroupBy._getitem_aggsS  s#     055u!%u555s   "c                    [        5         U R                  R                  nU R                  U5      nUR                  nUR                  5       (       a  UR                  5       S:  a  U" USS9$ U" U5      $ )a  Stub issue for `include_groups` [pandas-dev/pandas-stubs#1270].

- [User guide] mentions `include_groups` 4 times without deprecation.
- [`DataFrameGroupBy.apply`] doc says the default value of `True` is deprecated since `2.2.0`.
- `False` is explicitly the only *non-deprecated* option, but entirely omitted since [pandas-dev/pandas-stubs#1268].

[pandas-dev/pandas-stubs#1270]: https://github.com/pandas-dev/pandas-stubs/issues/1270
[User guide]: https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html
[`DataFrameGroupBy.apply`]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.apply.html
[pandas-dev/pandas-stubs#1268]: https://github.com/pandas-dev/pandas-stubs/pull/1268
)   r   F)include_groups)warn_complex_group_byrX   ro   _apply_exprs_functionapplyr~   r}   )rT   r   r   r   funcr   s         rG   r   PandasLikeGroupBy._apply_aggsX  sf     	~~--))%0>> 5 5 76 Ae44T{rI   c                   ^ ^^^ T R                   R                  5       mTR                  R                  mSUUUU 4S jjnU$ )Nc                &  > T
R                   R                  U 5      nT VVs/ s H8  nU" U5        H(  nUR                  R                  S   UR                  4PM*     M:     nnnU(       a  [        USS06O/ / 4u  pVT" XVT	S9R                  $ s  snnf )Nr   r   T)r   context)rX   r   rl   ilocrE   r   )r[   rX   rM   r   results	out_group	out_namesr   into_seriesr   rT   s          rG   fn3PandasLikeGroupBy._apply_exprs_function.<locals>.fnr  s    33B7I "!D OD !!!$dii0+ 1!  
 BI3#=#=rSUh Iy2FMMMs   ?B)r[   pd.DataFramer   zpd.Series[Any])rX   rh   _seriesr   )rT   r   r  r  r   s   `` @@rG   r   'PandasLikeGroupBy._apply_exprs_functionn  s7    ^^224jj..	N 	N 	rI   c              #    #    U R                   R                  " U R                  R                  5       40 U R                  D6n[
        R                  " 5          [
        R                  " SS[        S9  U R                  R                  nU H'  u  p4X2" U5      R                  " U R                  6 4v   M)     S S S 5        g ! , (       d  f       g = f7f)Nignorez#.*a length 1 tuple will be returned)messagecategory)r   rt   rr   r   rs   warningscatch_warningsfilterwarningsFutureWarningrX   r   r   r   )rT   r   with_nativekeygroups        rG   __iter__PandasLikeGroupBy.__iter__~  s     ,,&&tzz'8RD<Q<QR$$&##=&
 ..55K%
K.<<d>T>TUVV & '&&s   ACAB>5	C>
CC)	r   r   r   rs   re   rr   r   r   r   N)r   r   )r[   r   r   z(Sequence[PandasLikeExpr] | Sequence[str]r   r   r   r   )r   r   r   r   )r   zSequence[AggExpr]r[   r
  r   r   )r   zIterable[AggExpr]r   z#list[pd.DataFrame | pd.Series[Any]])r   r   r   Iterable[PandasLikeExpr]r   r
  )r   r  r   r   )r   z)Iterator[tuple[Any, PandasLikeDataFrame]])r   r   r   r   r   r   r   rY   rU   r   r   r   r   r   r  r   rQ   rI   rG   r   r      s   NuNN 	(N 	u	N
 	uN 	N 	uN 	uN 	vN 	IN 	N 	JN 	uN 	uN 	N  	!N" 	U#NKJ & '&EO  8((K ?? 7? ? 
?,-7^
.?

	
6&6	,6
$-E	, 
WrI   r   r   r   c                     Sn [        U 5      $ )zJDon't even attempt this, it's way too inconsistent across pandas versions.au  No results for group-by aggregation.

Hint: you were probably trying to apply a non-elementary aggregation with a pandas-like API.
Please rewrite your query such that group-by aggregations are elementary. For example, instead of:

    df.group_by('a').agg(nw.col('b').round(2).mean())

use:

    df.with_columns(nw.col('b').round(2)).group_by('a').agg(nw.col('b').mean())

)
ValueError)r   s    rG   r   r     s    	^  c?rI   c                 $    [        S[        5        g )Na)  Found complex group-by expression, which can't be expressed efficiently with the pandas API. If you can, please rewrite your query such that group-by aggregations are simple (e.g. mean, std, min, max, ...). 

Please see: https://narwhals-dev.github.io/narwhals/concepts/improve_group_by_operation/)r   UserWarningrQ   rI   rG   r   r     s    	W
 	rI   )rE   r4   rF   zUnpack[ScalarKwargs]r   r5   )r   r  )r   r   ):
__future__r   r  	functoolsr   	itertoolsr   operatorr   typingr   r   r	   r
   narwhals._compliantr   narwhals._exceptionsr   narwhals._expression_parsingr   narwhals._pandas_like.utilsr   narwhals.dependenciesr   collections.abcr   r   r   r   r   r   pandaspdpandas.api.typingr   _NativeGroupBytyping_extensionsr   narwhals._compliant.typingr   r   narwhals._pandas_like.dataframer   narwhals._pandas_like.exprr   r   r   r   r    r4   r5   r6   r;   rH   rK   r   r   r   rQ   rI   rG   <module>r2     sM   "    ! 8 8 , . J < :OO D(LC9OM9OCY C*1-*@ i @&			
	
	
	
			 '"  9 , hH
I H @  	  6 F B  2	& 	&D< D<NoW&(8:KKLoWdrI   