
    hhb7                    2   U d dl mZ d dlZd dlmZ d dlmZ d dlmZ d dl	m
Z
mZmZmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ e
r;d dlmZmZmZmZmZ d dlZd dl m!Z" d dl#m$Z$m%Z% d dl&m'Z'm(Z( d dl)m*Z* d dl+m,Z, dZ-de.d<   dZ/de.d<   ed         Z0de.d<   edddddddd d!d"d#d$d%d&d'd(d)d*d+e0f         Z1de.d,<   	 d-Z2de.d.<   	 eZ3de.d/<   	 d d0d1Z4d2e.d3<    ed45          dEd:            Z5 G d; d<          Z6 G d= d>ed?d@e1f                   Z7dFdBZ8dGdDZ9dS )H    )annotationsN)	lru_cache)chain)methodcaller)TYPE_CHECKINGAnyClassVarLiteral)EagerGroupBy)issue_warning)!evaluate_output_names_and_aliases)
zip_strict)is_pandas_like_dataframe)CallableIterableIteratorMappingSequence)DataFrameGroupBy)	TypeAlias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lastz,Mapping[NarwhalsAggregation, Literal[0, -1]]_REMAP_ORDERED_INDEX    )maxsizenamekwdsUnpack[ScalarKwargs]returnc                   | dk    rt          | d          S |r|                    d          dk    rt          |           S t          | fi |S )Nr,   F)dropnaddof   )r   get)r=   r>   s     U/var/www/histauto/venv/lib/python3.11/site-packages/narwhals/_pandas_like/group_by.py_native_aggrG   C   sb    yD//// "488F##q((D!!!%%%%%    c                      e Zd ZU dZded<   ded<   ded<   dd	ZddZddZddZddZ	ddZ
ddZddZed d            Zed!d            Zd"dZdS )#AggExpraM  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aliasesr@   Nonec                >    || _         d| _        d| _        d| _        d S )N  )rK   rL   rM   
_leaf_name)selfrK   s     rF   __init__zAggExpr.__init__[   s#    	57rH   group_byPandasLikeGroupByc               h    |j         }|j        }t          | j        ||          \  | _        | _        | S )zd**Mutating operation**.

        Stores the results of `evaluate_output_names_and_aliases`.
        )	compliantexcluder   rK   rL   rM   )rS   rU   dfrY   s       rF   with_expand_nameszAggExpr.with_expand_namesa   s=    
 "*KIr7+
 +
'4< rH   pd.DataFrame | pd.Series[Any]c                 	
 | j         }|                                 r/|                                 r|j                                        }n|                                 rV|j                                        |j                                                            fd|D                       }n}|                                 r|j        }| j	        
                    d          x}dk    rd| d|j         d}t          |          t          |          }|j        |j        |j        c	
|                                                    	
fd|D                       }n|                                 s|                                 rN |                                 |j        g |j        |                   }|                    |j        d	           nRt+          |          d
k    r|d         nt          |          } |                                 |j        |                   }t-          |          rt          | j                  |_        n| j        d         |_        |S )z8Evaluate the wrapped expression as a group_by operation.c                j    g | ]/}                                                   |          j        0S rP   )from_nativealiasnative).0r=   nsresult_singles     rF   
<listcomp>z)AggExpr._getitem_aggs.<locals>.<listcomp>y   s6    TTTd..44T::ATTTrH   keepr!   z`Expr.mode(keep='z7')` is not implemented in group by context for backend z3

Hint: Use `nw.col(...).mode(keep='any')` instead.c                   g | ]}  j         g |fi                                                     d                               |          j         fi |                             d                                          S )F)	ascendingrD   )groupbyr0   sort_valuesreset_indexhead
sort_index)rb   colkeyskwargsra   s     rF   re   z)AggExpr._getitem_aggs.<locals>.<listcomp>   s     	 	 	 NFN<T<3<::6::TVV [5[11 [%%T	- - &,	- - .1	2
 T!WWZ\\	 	 	rH   TinplacerD   r   )rL   is_lenis_top_level_function_groupedr0   rX   __narwhals_namespace___concat_horizontalis_moderp   rE   _implementationNotImplementedErrorlistra   _keys_kwargsis_lastis_first
native_agg	set_indexlenr   rM   columnsr=   )rS   rU   namesresultrX   rf   msgcolsselectro   rp   ra   rc   rd   s            @@@@@rF   _getitem_aggszAggExpr._getitem_aggsm   s   
 !;;== *	BT7799 *	B&++--FF[[]] (	B$-2244M#::<<B**TTTTTeTTT FF \\^^ "	B *I///E99H H H(8H H H 
 *#...;;D%F#>8+;LD& 1133B**	 	 	 	 	 	  $	 	 	 FF \\^^ 	Bt}} 	B&T__&&x'89R8>9RE9R'STTFX^T::::!$UqU1XXd5kkF&T__&&x'8'@AAF#F++ 	*!$,//FNN,q/FKrH   boolc                    | j         dk    S )Nr   	leaf_namerS   s    rF   rs   zAggExpr.is_len   s    ~&&rH   c                    | j         dk    S )Nr9   r   r   s    rF   r~   zAggExpr.is_last       ~''rH   c                    | j         dk    S )Nr8   r   r   s    rF   r   zAggExpr.is_first   s    ~((rH   c                    | j         dk    S )Nr*   r   r   s    rF   rx   zAggExpr.is_mode   r   rH   c                "    | j         j        dk    S )Nr   )rK   _depthr   s    rF   rt   zAggExpr.is_top_level_function   s    y1$$rH   r   c                    | j         j        S N)rK   _scalar_kwargsr   s    rF   rp   zAggExpr.kwargs   s    y''rH   NarwhalsAggregation | Anyc                n    | j         x}r|S t                               | j                  | _         | j         S r   )rR   rV   rK   )rS   r=   s     rF   r   zAggExpr.leaf_name   s5    ?"4 	K+66tyAArH   r5   c                    t                               | j                  }| j        t          v r!t	          dt          | j                           S t          |fi | j        S )z@Return a partial `DataFrameGroupBy` method, missing only `self`.r+   )n)rV   _remap_expr_namer   r:   r   rG   rp   )rS   native_names     rF   r   zAggExpr.native_agg   sX    '88HH>111)=dn)MNNNN;66$+666rH   N)rK   r   r@   rN   )rU   rV   r@   rJ   )rU   rV   r@   r\   )r@   r   )r@   r   )r@   r   )r@   r5   )__name__
__module____qualname____doc____annotations__rT   r[   r   rs   r~   r   rx   rt   propertyrp   r   r   rP   rH   rF   rJ   rJ   L   s;          8 8 8 8
 
 
 
5 5 5 5n' ' ' '( ( ( () ) ) )( ( ( (% % % % ( ( ( X(    X7 7 7 7 7 7rH   rJ   c                      e Zd ZU i ddddddddddddddddd	d
ddddddddddddddZded<   ded<   	 ded<   	 ded<   	 ded<   	 ed8d            Zd9d&Zd:d)Zd;d-Z	d<d0Z
d=d2Zd>d4Zd?d6Zd7S )@rV   r2   r'   r(   r&   r)   r*   r1   r3   r   r0   n_uniquer,   r#   r.   r"   r!   r8   r+   r9   z9ClassVar[Mapping[NarwhalsAggregation, NativeAggregation]]_REMAP_AGGStuple[str, ...]_original_columnsz	list[str]r|   _output_key_nameszMapping[str, bool]r}   r@   c                    | j         S )z>Group keys to ignore when expanding multi-output aggregations.)_excluder   s    rF   rY   zPandasLikeGroupBy.exclude   s     }rH   rZ   r   ro   (Sequence[PandasLikeExpr] | Sequence[str]drop_null_keysr   rN   c                 t          |j                  | _        || _        |                     ||          \  | _        | _        | _        g | j        | j        R | _        | j	        j
        }t          |j        j                                      | j	        j                  r|                    d          }dd|dd| _         |j        | j                                        fi | j        | _        d S )NT)dropF)sortas_indexrB   observed)tupler   r   _drop_null_keys_parse_keys_compliant_framer|   r   r   rX   ra   setindexr   intersectionrk   r}   ri   copyru   )rS   rZ   ro   r   ra   s        rF   rT   zPandasLikeGroupBy.__init__   s     "'rz!2!2-DHDTDTE
 E
Atz4+A *P4:)O8N)O)O &v|!""//0FGG 	3''T'22F $	
 
 (6v~djoo6G6G'X'X4<'X'XrH   exprsr   c                   d}g }|D ]N}|                     t          |                              |                      |                     |          sd}O|r|rB| j                                        }|                    |                     |                    }n| j                                        	                    t          | j        j                  | j                  }n4| j        j        j        rt!                      |                     |          }|                    d           |                     ||          S )NTF)r   rq   )appendrJ   r[   
_is_simplerX   rv   rw   r   __native_namespace__	DataFramer{   ru   groupsr|   ra   emptyempty_results_error_apply_aggsrk   _select_results)rS   r   all_aggs_are_simple	agg_exprsrK   rc   r   s          rF   aggzPandasLikeGroupBy.agg	  sD   "#%	 	, 	,DWT]]<<TBBCCC??4(( ,&+# 	- ^::<<..t/A/A)/L/LMM<<>>HH-..
 I   ^"( 	-%'''%%e,,F 	4(((##FI666rH   r   Sequence[AggExpr]pd.DataFramec               
   t          j        d |D                       } | j                            |d          j        g | j        |R                      t          t          | j        | j	                                      S )zgResponsible for remapping temp column names back to original.

        See `ParseKeysGroupBy`.
        c              3  $   K   | ]}|j         V  d S r   )rM   )rb   es     rF   	<genexpr>z4PandasLikeGroupBy._select_results.<locals>.<genexpr>*  s$      'E'Ea	'E'E'E'E'E'ErH   F)validate_column_names)
r   from_iterablerX   _with_nativesimple_selectr|   renamedictzipr   )rS   rZ   r   	new_namess       rF   r   z!PandasLikeGroupBy._select_results#  s     ''E'E9'E'E'EEE	DN''%'HH4 J4)24 4 4VDTZ)?@@AABB	
rH   Iterable[AggExpr]#list[pd.DataFrame | pd.Series[Any]]c                      fd|D             S )Nc                :    g | ]}|                               S rP   )r   )rb   r   rS   s     rF   re   z3PandasLikeGroupBy._getitem_aggs.<locals>.<listcomp>4  s%    555!%%555rH   rP   )rS   r   s   ` rF   r   zPandasLikeGroupBy._getitem_aggs1  s     6555u5555rH   Iterable[PandasLikeExpr]c                    t                       | j        j        }|                     |          }| j        j        }|                                r%|                                dk    r ||d          S  ||          S )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   ry   _apply_exprs_functionru   apply	is_pandas_backend_version)rS   r   implfuncr   s        rF   r   zPandasLikeGroupBy._apply_aggs6  s     	~-))%00#>> 	5 5 5 7 76 A A5e4444uT{{rH   r   c                j      j                                         j        j        d fd}|S )NrZ   r   r@   pd.Series[Any]c                    j                             |           fdD             }|r	t          | ng g f\  }} ||          j        S )Nc              3  f   K   | ]+} |          D ]}|j         j        d          |j        fV  ,dS )r   N)ra   ilocr=   )rb   rK   ro   rX   s      rF   r   zFPandasLikeGroupBy._apply_exprs_function.<locals>.fn.<locals>.<genexpr>P  sg         DOO   !!$di0      rH   )r   context)rX   r   r   ra   )	rZ   results	out_group	out_namesrX   r   into_seriesrc   rS   s	       @rF   fnz3PandasLikeGroupBy._apply_exprs_function.<locals>.fnN  s{    33B77I   !  G
 <C#P:w#7#7R Iy;y	2FFFMMrH   )rZ   r   r@   r   )rX   rv   _seriesr   )rS   r   r   r   rc   s   `` @@rF   r   z'PandasLikeGroupBy._apply_exprs_functionJ  s`    ^2244j.	N 	N 	N 	N 	N 	N 	N 	N 	N 	rH   )Iterator[tuple[Any, PandasLikeDataFrame]]c              #    K   t          j                    5  t          j        ddt                     | j        j        }| j        D ]!\  }}|  ||          j        | j         fV  "	 d d d            d S # 1 swxY w Y   d S )Nignorez#.*a length 1 tuple will be returned)messagecategory)	warningscatch_warningsfilterwarningsFutureWarningrX   r   ru   r   r   )rS   with_nativekeygroups       rF   __iter__zPandasLikeGroupBy.__iter__Z  s     $&& 	W 	W#=&   
 .5K"m W W
U<KK..<d>TUVVVVVW	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	Ws   AA66A:=A:N)r@   r   )rZ   r   ro   r   r   r   r@   rN   )r   r   r@   r   )r   r   rZ   r   r@   r   )r   r   r@   r   )r   r   r@   r   )r   r   r@   r   )r@   r   )r   r   r   r   r   r   rY   rT   r   r   r   r   r   r   rP   rH   rF   rV   rV      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K    $ '&&&EO    8K   XY Y Y Y87 7 7 74
 
 
 
6 6 6 6
   (    	W 	W 	W 	W 	W 	WrH   rV   r   r   
ValueErrorc                 $    d} t          |           S )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())

)r   )r   s    rF   r   r   f  s    	^  c??rH   rN   c                 0    t          dt                     d S )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   UserWarningrP   rH   rF   r   r   u  s)    	W
 	    rH   )r=   r4   r>   r?   r@   r5   )r@   r   )r@   rN   ):
__future__r   r   	functoolsr   	itertoolsr   operatorr   typingr   r   r	   r
   narwhals._compliantr   narwhals._exceptionsr   narwhals._expression_parsingr   narwhals._utilsr   narwhals.dependenciesr   collections.abcr   r   r   r   r   pandaspdpandas.api.typingr   _NativeGroupBytyping_extensionsr   r   narwhals._compliant.typingr   r   narwhals._pandas_like.dataframer   narwhals._pandas_like.exprr   r   r   r   r    r4   r5   r6   r:   rG   rJ   rV   r   r   rP   rH   rF   <module>r     sL   " " " " " " "              ! ! ! ! ! ! 8 8 8 8 8 8 8 8 8 8 8 8 , , , , , , . . . . . . J J J J J J & & & & & & : : : : : : POOOOOOOOOOOOOODDDDDD33333333LLLLLLLLCCCCCC999999OMOOOOC C C C C*1-*@  @ @ @ @&			
	
	
	
			 '"      , hH
 H H H H @       6 F F      2& & & &x7 x7 x7 x7 x7 x7 x7 x7v\W \W \W \W \W&(8:KKL\W \W \W~        rH   