
    g8                    f   d dl mZ d dl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 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 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 d dlmZ erd dlmZ d dlmZ d dlmZ d dlmZ ddddddddddd 
Z G d! d"      Z 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d$d#Z!y)%    )annotationsN)copy)TYPE_CHECKING)Any)Callable)Iterator)Sequence)is_simple_aggregation)parse_into_exprs)horizontal_concat)native_series_from_iterable)select_columns_by_name)set_columns)Implementation)find_stacklevel)remove_prefixPandasLikeDataFrame)PandasLikeSeries)IntoPandasLikeExpr)CompliantExprsummeanmedianmaxminstdvarsizenuniquecount)
r   r   r   r   r   r   r   lenn_uniquer!   c                  H    e Zd Z	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 ddZddZd	dZy)
PandasLikeGroupByc                  || _         || _        | j                   j                  t        j                  u r| j                   j
                  dk  r|st        | j                   j                  | j                  | j                   j
                  | j                   j                        j                         j                         j                         rd}t        |      | j                   j                  j                  t        | j                        ddd      | _        y | j                   j                  j                  t        | j                        dd|d      | _        y )N)   r'   z:Grouping by null values is not supported in pandas < 1.0.0FT)sortas_indexobserved)r(   r)   dropnar*   )_df_keys_implementationr   PANDAS_backend_versionr   _native_frameisnaanyNotImplementedErrorgroupbylist_grouped)selfdfkeysdrop_null_keysmsgs        S/var/www/openai/venv/lib/python3.12/site-packages/narwhals/_pandas_like/group_by.py__init__zPandasLikeGroupBy.__init__+   s    
HH$$(=(==))F2 #*HH**JJHH--HH,,	  S)#.. HH22::TZZ 	 ; DM !HH22::TZZ % ; DM    c                   t        |d| j                  j                         i|}| j                  j                  }t	        | j
                        }|D ]6  }|j                  d}t        |      |j                  |j                         8 t        | j                  || j
                  || j                  | j                  j                  j                  || j                  j                  | j                  j                         	      S )N	namespacezAnonymous expressions are not supported in group_by.agg.
Instead of `nw.all()`, try using a named expression, such as `nw.col('a', 'b')`
)dataframe_is_emptyimplementationbackend_versionnative_namespace)r   r,   __narwhals_namespace__r.   r   r-   _output_names
ValueErrorextend
agg_pandasr7   _from_native_framer1   emptyr0   __native_namespace__)r8   aggs
named_aggsexprsrC   output_namesexprr<   s           r=   aggzPandasLikeGroupBy.aggQ   s    
 !
hh557
 

 *.)A)A"&tzz"2D!!)+ 
 !o% 2 23  MMJJ###xx55;;) HH55!XX::<

 
	
r?   c                    ddl m}  ||| j                  j                  | j                  j                  | j                  j
                        S )Nr   r   )rC   rD   version)narwhals._pandas_like.dataframer   r,   r.   r0   _version)r8   r9   r   s      r=   rK   z$PandasLikeGroupBy._from_native_frames   s<    G"8833 HH55HH%%	
 	
r?   c              #     K   t        j                         5  t        j                  ddt               | j                  D ]  \  }}|| j                  |      f  	 d d d        y # 1 sw Y   y xY ww)Nignorez#.*a length 1 tuple will be returned)messagecategory)warningscatch_warningsfilterwarningsFutureWarningr7   rK   )r8   keygroups      r=   __iter__zPandasLikeGroupBy.__iter__}   s^     $$&##=&
 #mm
UD33E:;; , '&&s   A3AA'	A3'A0,A3N)r9   r   r:   	list[str]r;   boolreturnNone)rN   r   rO   r   re   r   )r9   r   re   r   )re   z)Iterator[tuple[Any, PandasLikeDataFrame]])__name__
__module____qualname__r>   rS   rK   rb    r?   r=   r%   r%   *   sT    $%$-6$KO$	$L 
! 
 ) 
 
	 
D
<r?   r%   c                  d}	D ]-  }
t        |
      rt        |
j                  d      t        v r+d}	 n i }t	        j
                  t              }t	        j
                  d       }t	        j
                  d       }g }g }|	rFD ]
  }
|
j                  dk(  r|
j                  d}t        |      t        j                  |
j                  |
j                        }|
j                  D ]C  }|j                  |       |j                  |d    d|        ||d      j                  |       E |
j                  d	k7  s|
j                  |
j                  d}t        |      t        |
j                  d      }t        j                  ||      }|d
k(  }|dk(  }|dk(  }|
j                  j                  dd	      }t        |
j                  |
j                        D ]  \  }}|r|||<   |r4|d	k7  r/||   d   j                  |       ||   d	   j                  |       D|r4|d	k7  r/||   d   j                  |       ||   d	   j                  |       z|j                  |       |j                  | d|        ||   j                  |         g }|r/| j                  |      }|j                   D cg c]  \  }}| d|  c}}|_        t#        |j                         t#        |      k(  r!t%        |j                         t%        |      k(  sd| d|j                    d}t        |      t	        j
                  t              }t'        |      D ]  \  }}||   j                  |        |j                   D cg c]  }||   j)                  d       } }| D !cg c]  }!||!   	 }}!||_        |j                  |       |r[| t        |j+                                  j-                  d      }"t        |j/                               |"_        |j                  |"       |rW|j1                  |j3                         D #$cg c]*  \  }\  }#}$t5        | |#   j7                  |      |$|      , c}$}#}       |rW|j1                  |j3                         D %&cg c]*  \  }\  }%}&t5        | |%   j9                  |      |&|      , c}&}%}       |rt	        j:                  |D '(cg c]  }'|'D ]  }(|(  c}(}'      })t=        d |)j+                         D              r<d}|)j3                         D ]  \  }*}+|+d	kD  r|d|* d|+ dz  } d| }t?        |      tA        ||      },n4|jC                  t        | jD                  j/                               |      },|,jG                  d        tI        |,||            S |rd}t?        |      tK        jL                  dtN        tQ                      d#fd }-tR        jT                  u r|d!k\  r| jW                  |-d"      }.n| jW                  |-      }.|.jG                  d        tI        |.||            S c c}}w c c}w c c}!w c c}$}#}w c c}&}%}w c c}(}'w )$zThis should be the fastpath, but cuDF is too far behind to use it.

    - https://github.com/rapidsai/cudf/issues/15118
    - https://github.com/rapidsai/cudf/issues/15084
    Tzcol->Fc                 
    g g fS Nrj   rj   r?   r=   <lambda>zagg_pandas.<locals>.<lambda>       Rr?   c                 
    g g fS rm   rj   rj   r?   r=   rn   zagg_pandas.<locals>.<lambda>   ro   r?   r   z_Safety assertion failed, please report a bug to https://github.com/narwhals-dev/narwhals/issues_r'   r    r   r   ddofz"Safety assertion failed, expected z got zH, please report a bug at https://github.com/narwhals-dev/narwhals/issues)r+   )rr   )columnsrC   rD   c              3  &   K   | ]	  }|d kD    ywr'   Nrj   ).0vs     r=   	<genexpr>zagg_pandas.<locals>.<genexpr>)  s     @"?Q1q5"?s    z
- 'z' z timesz"Expected unique output names, got:)dfsrC   rD   )rs   )inplaceau  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())

a5  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/pandas_like_concepts/improve_group_by_operation/)
stacklevelc                B   g }g }D ]  } | |             }t        d |D              sd|j                   d}t        |      |D ]E  }|j                  |j                  j
                  d          |j                  |j                         G  t        ||d	      S )Nc              3  8   K   | ]  }t        |      d k(    ywru   )r"   )rv   xs     r=   rx   z+agg_pandas.<locals>.func.<locals>.<genexpr>^  s     9Lqs1v{Ls   zAggregation 'z' failed to aggregate - does your aggregation function return a scalar?                 

 Please see: https://narwhals-dev.github.io/narwhals/pandas_like_concepts/improve_group_by_operation/r   ry   )indexnamerC   )all_function_namerH   append_native_seriesilocr   r   )
r9   	out_group	out_namesrR   results_keysr<   result_keysrP   from_dataframerC   s
          r=   funczagg_pandas.<locals>.funcY  s    		Dr 23L9L99%d&9&9%: ;z { !o%+  !;!;!@!@!CD  !1!12  ,  +)	
 	
r?   )   r   )include_groups)r9   r   re   r   ),r
   r   r   POLARS_TO_PANDAS_AGGREGATIONScollectionsdefaultdictr6   _depthrG   AssertionErrorgetr   _root_names_kwargsziprS   rs   setr"   	enumeratepopvaluesr    r:   rI   itemsr   r   r   Counterr3   rH   r   	DataFramegroupsreset_indexr   r\   warnUserWarningr   r   r/   apply)/groupedrP   r:   rQ   r   rC   rD   rB   rE   all_aggs_are_simplerR   nunique_aggssimple_aggsstd_aggsvar_aggsexpected_old_names	new_namesr<   function_nameoutput_nameis_n_uniqueis_stdis_varrr   	root_nameresult_aggsresult_simple_aggsabexpected_old_names_indicesidxitem	index_mapiresult_nunique_aggsstd_root_namesstd_output_namesvar_root_namesvar_output_namesframecoutput_names_counterr`   valueresultr   result_complexs/    `  ``                                         r=   rJ   rJ      s   " !$'d117;,- #(  $&L(3(?(?(EK 8C7N7N8H 8C7N7N8H %'ID{{a%%-{C(-- = A A'')<)<! $(#5#5K$$[1&--a	=/.JKQ(//> $6  q D$4$4$<@R@R@Zw$S)))$*=*=wGM9==}M (94K"e+F"e+F<<##FA.D*-d.>.>@R@R*S&	;09L-	TN1%,,Y7TN1%,,[9	TN1%,,Y7TN1%,,[9$$[1&--1]O.LM	*11-@ +TA \ !([!9'9'A'A*'Atq!1#Qqc
'A*& &../37I3JJ*223s;M7NN 99K8L M-556 7]] 
 %S)) @K?V?V@& ''9:	T*4077< ; /66$6D +4044Q76  $ 099y!1yI9)2&12")$|/B/B/D*E"F"N"N #O # +/|/@/@/B*C'23 EMNNDT EU@@~/?  /333> 0'5(7	 EU
  EMNNDT EU@@~/?  /333> 0'5(7	 EU
 #.#6#6 +;uUU;$  @"6"="="?@@"6"<"<">JCqyse2eWF;;	 #?
 ;3%@ o%&- /F &//W^^5H5H5J0KUY/ZF 	4("6<.Y
 	
 b 	 oMM	c
 	"$
( ...?f3L tEB t, t,L/>	
 _*($ : <s$   ;Y)Y/$Y4/Y9!/Z /Z
)r   r   rP   z)Sequence[CompliantExpr[PandasLikeSeries]]r:   rc   rQ   rc   r   z$Callable[[Any], PandasLikeDataFrame]rC   r   rD   ztuple[int, ...]rB   rd   rE   r   re   r   )"
__future__r   r   r\   r   typingr   r   r   r   r	   narwhals._expression_parsingr
   r   narwhals._pandas_like.utilsr   r   r   r   narwhals.utilsr   r   r   rV   r   narwhals._pandas_like.seriesr   narwhals._pandas_like.typingr   narwhals.typingr   r   r%   rJ   rj   r?   r=   <module>r      s    "          > 9 9 C > 3 ) * (C=?- ! [< [<|rr4r r 	r
 9r r %r r r rr?   