U
    sVc                     @  s  d dl mZ d dlZd dlmZ d dlmZ d dlZd dlZd dl	m
Z
mZmZmZmZmZmZmZmZmZ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mZmZm Z m!Z!m"Z"m#Z# d d	l$m%Z%m&Z& d d
l'm(Z( d dl)m*Z*m+Z+ d dl,m-Z- d dl.m/Z/m0Z0m1Z1m2Z2 d dl3m4Z4m5Z5m6Z6 d dl7m8Z8 d dl9m:Z: d dl;m<  m=Z> d dl?m@Z@mAZA e
rd dlBmCZCmDZDmEZE d dlFmGZG d dlHmIZI d dlJmKZK eeLef ZMdTdddddddddZNG d d! d!ejOd"ZPG d#d$ d$ePZQG d%d deQZRG d&d' d'eRZSG d(d) d)eRZTG d*d+ d+eQZUG d,d- d-ePZVG d.d/ d/ePZWd0d1d2d3d4ZXdd5d6d7ZYd8d9d:d;d<ZZd=d=d>d?d@Z[dAdBdCdDdEdFdGdHZ\dIdIdJdKdLZ]dMdMdNdOdPZ^d8dQd:dRdSZ_dS )U    )annotationsN)defaultdict)partial)TYPE_CHECKINGAnyCallableDefaultDictDictHashableIterableIteratorListSequencecast)option_context)lib)AggFuncTypeAggFuncTypeBaseAggFuncTypeDict
AggObjTypeAxisNDFrameTnpt)	DataErrorSpecificationError)cache_readonly)find_stack_levelrewrite_warning)is_nested_object)is_dict_likeis_extension_array_dtypeis_list_likeis_sequence)ABCDataFrame
ABCNDFrame	ABCSeries)	safe_sort)SelectionMixin)!create_series_with_explicit_dtypeensure_wrapped_if_datetimelike)	DataFrameIndexSeries)GroupBy)	Resampler)
BaseWindowFr*   r   r   bool
str | None
FrameApply)objfuncaxisrawresult_typereturnc                 C  s8   |  |}|dkrt}n|dkr$t}|| |||||dS )z=construct and return a row or column based frame apply objectr      r6   r7   argskwargs)_get_axis_numberFrameRowApplyFrameColumnApply)r3   r4   r5   r6   r7   r;   r<   klass rA   5/tmp/pip-unpacked-wheel-xj8nt62q/pandas/core/apply.pyframe_applyR   s    

rC   c                   @  s   e Zd ZU ded< ddddddd	Zejd
dddZddddZd
dddZ	dd Z
d
dddZd
dddZd
dddZd
dddZd
dddZdd
d d d!d"d#Zdd$d%d&Zd'S )(Applyintr5   r   r0   r1   None)r3   r6   r7   r8   c                   s|   || _ || _ pd| _pi | _|dkr0td|| _s> rhttjt	fsht
sh fdd}n}| _|| _d S )NrA   )Nreduce	broadcastexpandzUinvalid value for result_type, must be one of {None, 'reduce', 'broadcast', 'expand'}c                   s   | f S NrA   )xr;   r4   r<   rA   rB   f   s    zApply.__init__.<locals>.f)r3   r6   r;   r<   
ValueErrorr7   
isinstancenpufuncstrr!   orig_frM   )selfr3   r4   r6   r7   r;   r<   rM   rA   rL   rB   __init__p   s*    	

zApply.__init__DataFrame | Seriesr8   c                 C  s   d S rJ   rA   rT   rA   rA   rB   apply   s    zApply.applyzDataFrame | Series | Nonec              
   C  s   | j }| j}| j}| j}t|tr*|  S t|r:|  S t	|rJ| 
 S t|rt|}|r|s|sd}d| d}t|t| t|| W  5 Q R  S Q R X dS )z
        Provide an implementation for the aggregators.

        Returns
        -------
        Result of aggregation, or None if agg cannot be performed by
        this method.
        !The default value of numeric_onlyThe operation  failed on a column. If any error is raised, this will raise an exception in a future version of pandas. Drop these columns to avoid this warning.N)r3   rM   r;   r<   rO   rR   	apply_strr   agg_dict_liker!   agg_list_likecallablecomget_cython_funcr   FutureWarninggetattr)rT   r3   argr;   r<   rM   old_msgnew_msgrA   rA   rB   agg   s&    	


z	Apply.aggc              
     sf  | j }| j | j}| j}| j}|jdk}||dkrV|r>t|jj	 df||jS t
 rt sttt   |rdd  D  n fdd|D  t rtt  |  S tt  z|  }W nB tk
r    Y n. tk
r } ztd|W 5 d}~X Y nX t|ttfr:|jr:|js:tdt|ttfrZ|j|jsbtd|S )	aI  
        Transform a DataFrame or Series.

        Returns
        -------
        DataFrame or Series
            Result of applying ``func`` along the given axis of the
            Series or DataFrame.

        Raises
        ------
        ValueError
            If the transform function fails or does not transform.
        r9   r   c                 S  s   i | ]}t |p||qS rA   ra   get_callable_name.0vrA   rA   rB   
<dictcomp>   s      z#Apply.transform.<locals>.<dictcomp>c                   s   i | ]
}| qS rA   rA   )rl   colr4   rA   rB   rn      s      Transform function failedNFunction did not transform)r3   rS   r5   r;   r<   ndimr=   AssertionErrorT	transformr!   r   r   r   r   r   transform_dict_liketransform_str_or_callable	TypeError	ExceptionrN   rO   r%   r#   emptyindexequals)rT   r3   r5   r;   r<   Z	is_seriesresulterrrA   rp   rB   rv      sH    



zApply.transformc                 C  s.  ddl m} | j}| j}| j}t|ts,tt|dkr@t	d| 
d||}i }g }d}| D ]\}	}
|j|	dd}z|j|
df||||	< W qb tk
r } z.t|dkr|nt|tsd	}||	 W 5 d
}~X Y qbX qb|s|rtnt	}|dt|dkr"tj| dtt d ||ddS )zC
        Compute transform in the case of a dict-like func
        r   concat$No transform functions were providedrv   Tr9   rs   >   r   rr   FNrq   z did not transform successfully. If any error is raised, this will raise in a future version of pandas. Drop these columns/ops to avoid this warning.
stacklevelr5   )pandas.core.reshape.concatr   r3   r;   r<   rO   r$   rt   lenrN   normalize_dictlike_argitems_gotitemrv   rz   rR   ry   appendwarningswarnrc   r   )rT   r4   r   r3   r;   r<   resultsfailed_namesZall_type_errorsnamehowcolgr   r@   rA   rA   rB   rw     s>    
zApply.transform_dict_likec              
   C  s   | j }| j}| j}t|tr0| j||f||S |s|st|}|rd}d| d}t|t	| t
|| W  5 Q R  S Q R X z|j|fd|i|W S  tk
r   ||f|| Y S X dS )zL
        Compute transform in the case of a string or callable func
        rZ   r[   r\   r;   N)r3   r;   r<   rO   rR   _try_aggregate_string_functionra   rb   r   rc   rd   rY   rz   )rT   r4   r3   r;   r<   rM   rf   rg   rA   rA   rB   rx   5  s"    


zApply.transform_str_or_callablec                   s2  ddl m} | j}ttt | j}t|dddkr:tdt	|t
sJ|}n|jjdkr^|j}n|j}g }g }g }d}|jdkr|D ]p}	|j|jd|d}
z|
|	}W n( tk
r   |t|	p|	 Y qX || t|	p|	}|| qn`g }t|D ]D\}}|j|d|jdd|f d}
ztjd	d
}|
|}W 5 Q R X t|dkrt|d}|D ]@}t|t|jr|| ntj |j|j!|j"|j#d qrW n| tt$fk
r   || Y nn t%k
r2 } z:dt|kr|| ndt|kr || n W 5 d}~X Y nX || || q|j&'|}t|sjt%dt|dkrtj(||t)t* d z|||ddd}W n\ tk
r  } z<ddl+m,} ||||jd}t-|rt%d|| W Y S d}~X Y n.X |j.j/ t0 fdd|D }|j1|ddS dS )z
        Compute aggregation in the case of a list-like argument.

        Returns
        -------
        Result of aggregation.
        r   r   r5   r9   "axis other than 0 is not supportedz{} did not aggregate successfully. If any error is raised this will raise in a future version of pandas. Drop these columns/ops to avoid this warning.)rs   ZsubsetNT)recordz.*)messagecategoryfilenamelinenozMust produce aggregated valuez
no resultsr   F)keysr5   sortr,   )r|   r   z3cannot combine transform and aggregation operationsc                 3  s    | ]}|j j kr|j V  qd S rJ   )r|   size)rl   r~   Z
index_sizerA   rB   	<genexpr>  s     z&Apply.agg_list_like.<locals>.<genexpr>copy)2r   r   r3   r   r   r   rM   rd   NotImplementedErrorrO   r'   _selected_objrs   Z_obj_with_exclusionsr   r   	aggregatery   r   ra   rj   	enumerateZilocr   catch_warningsr   recompileformatmatchrR   r   warn_explicitr   r   r   r   rN   columnsZtaker   rc   r   pandasr,   r   r|   r   nextreindex)rT   r   r3   re   selected_objr   r   r   Zdepr_nuisance_columns_msgar   Znew_resr   indicesr|   ro   r   r   warningr   Zconcatenatedr,   r~   Zfull_ordered_indexrA   r   rB   r_   R  s    





zApply.agg_list_likec                   s  ddl m} ddlm} | jtt| j}tdddkrBt	dt
tsV}d}nj}j}| d||}|jdkrj|dd	  fd
d| D nfdd| D t| }dd  D }t|rXfdd|D }|g kr|n|}|jdkr&||}	|	|jj |	}t
tr6dnd}
|fdd|D |
|d}nNt|rltdn:ddl m} jdkrtdj}nd}||d}|S )z
        Compute aggregation in the case of a dict-like argument.

        Returns
        -------
        Result of aggregation.
        r   r+   r   r5   r9   r   Nrh   r   c                   s   i | ]\}}|  |qS rA   )rh   rl   keyr   )r   rA   rB   rn     s      z'Apply.agg_dict_like.<locals>.<dictcomp>c                   s&   i | ]\}}| j |d d|qS )r9   r   )r   rh   r   )r3   rA   rB   rn     s     c                 S  s   g | ]}t |tqS rA   )rO   r$   )rl   rrA   rA   rB   
<listcomp>   s     z'Apply.agg_dict_like.<locals>.<listcomp>c                   s   g | ]} | j s|qS rA   )r{   rl   kr   rA   rB   r     s     
    c                   s   i | ]}| | qS rA   rA   r   r   rA   rB   rn     s      )r5   r   zLcannot perform both aggregation and transformation operations simultaneouslyr   r,   )r   )r   r+   r   r   r3   r   r   rM   rd   r   rO   r'   r   Z
_selectionr   rs   r   r   listr   valuesallZ
_set_namesr   namesr%   anyrN   r,   r   )rT   r+   r   re   r   Z	selectionr   Z
is_ndframeZkeys_to_useZktur5   r~   r,   r   rA   )r   r3   r   rB   r^     sX    



  

zApply.agg_dict_likec                 C  s   t t| j}| j}t||d}t|rt|}|j|j	}| j
dkrhd|ksV|dkrhtd| dn0d|kr~| j
| jd< n| j
dkrtd| d| j||f| j| jS )zy
        Compute apply in case of a string.

        Returns
        -------
        result: Series or DataFrame
        Nr   r5   )ZcorrwithZmadZskewz
Operation z does not support axis=1)r   rR   rM   r3   rd   r`   inspectgetfullargspecr;   
kwonlyargsr5   rN   r<   r   )rT   rM   r3   r4   sig	arg_namesrA   rA   rB   r]   (  s"    	


zApply.apply_strc                 C  s   | j j| j| jf| j| jS )z
        Compute apply in case of a list-like or dict-like.

        Returns
        -------
        result: Series, DataFrame, or None
            Result when self.f is a list-like or dict-like, None otherwise.
        )r3   r   rM   r5   r;   r<   rX   rA   rA   rB   apply_multipleF  s    	zApply.apply_multiplerR   r   )r   r3   r4   r8   c           	        s   |dkst |dkr4t|tr4tdd | D sJtdd | D rRtd|jdkrt| t|j	 }t
|dkrttt|}td	| d
tttf t fdd| D ri }| D ]&\}}t| s|g||< q|||< q|}|S )a  
        Handler for dict-like argument.

        Ensures that necessary columns exist if obj is a DataFrame, and
        that a nested renamer is not passed. Also normalizes to all lists
        when values consists of a mix of list and non-lists.
        )rY   rh   rv   rh   c                 s  s   | ]\}}t |V  qd S rJ   )r!   rl   _rm   rA   rA   rB   r   a  s     z/Apply.normalize_dictlike_arg.<locals>.<genexpr>c                 s  s   | ]\}}t |V  qd S rJ   )r   r   rA   rA   rB   r   b  s     znested renamer is not supportedr9   r   z
Column(s) z do not existc                 3  s   | ]\}}t | V  qd S rJ   )rO   )rl   r   rK   Zaggregator_typesrA   rB   r   s  s     )rt   rO   r%   r   r   r   rs   setr   r   r   r   r&   KeyErrortupledict)	rT   r   r3   r4   colsZcols_sortednew_funcr   rm   rA   r   rB   r   Q  s0    




zApply.normalize_dictlike_arg)re   c                 O  s   t |tstt||d}|dk	rbt|r4|||S t|dksDttdd |D dks^t|S tt|d}|dk	rt|dr||f||S td| dt	|j
 ddS )	z
        if arg is a string, then try to operate on it:
        - try to find a function (or attribute) on ourselves
        - try to find a numpy function
        - raise
        Nr   c                 S  s   g | ]}|d kr|qS )r   rA   )rl   kwargrA   rA   rB   r     s      z8Apply._try_aggregate_string_function.<locals>.<listcomp>Z	__array__'z' is not a valid function for 'z' object)rO   rR   rt   rd   r`   r   rP   hasattrAttributeErrortype__name__)rT   r3   re   r;   r<   rM   rA   rA   rB   r   }  s    
z$Apply._try_aggregate_string_functionN)r   
__module____qualname____annotations__rU   abcabstractmethodrY   rh   rv   rw   rx   r_   r^   r]   r   r   r   rA   rA   rA   rB   rD   m   s   
&'C1 Q,rD   )	metaclassc                   @  s4   e Zd ZdZeddddZeddddZdS )	NDFrameApplyzg
    Methods shared by FrameApply and SeriesApply but
    not GroupByApply or ResamplerWindowApply
    r+   rW   c                 C  s   | j jS rJ   )r3   r|   rX   rA   rA   rB   r|     s    zNDFrameApply.indexc                 C  s   | j | jS rJ   )r3   Z_get_agg_axisr5   rX   rA   rA   rB   agg_axis  s    zNDFrameApply.agg_axisN)r   r   r   __doc__propertyr|   r   rA   rA   rA   rB   r     s
   r   c                      s0  e Zd ZU ded< eejddddZeejddddZeejd	dd
dZ	ejddddddZ
eddddZeddddZedd ZeddddZddddZ fddZdd Zd d! Zddd"d#d$Zd%d& Zd'dd(d)Zddddd*d+Zdd fd,d-Z  ZS ).r2   r*   r3   r+   rW   c                 C  s   d S rJ   rA   rX   rA   rA   rB   result_index  s    zFrameApply.result_indexc                 C  s   d S rJ   rA   rX   rA   rA   rB   result_columns  s    zFrameApply.result_columnszIterator[Series]c                 C  s   d S rJ   rA   rX   rA   rA   rB   series_generator  s    zFrameApply.series_generatorResTyperV   r   	res_indexr8   c                 C  s   d S rJ   rA   rT   r   r   rA   rA   rB   wrap_results_for_axis  s    z FrameApply.wrap_results_for_axisc                 C  s   | j S rJ   )r   rX   rA   rA   rB   res_columns  s    zFrameApply.res_columnsc                 C  s   | j jS rJ   )r3   r   rX   rA   rA   rB   r     s    zFrameApply.columnsc                 C  s   | j jS rJ   )r3   r   rX   rA   rA   rB   r     s    zFrameApply.valuesr,   c                 C  s   | j jS rJ   )r3   dtypesrX   rA   rA   rB   r     s    zFrameApply.dtypesc              	   C  s   t | jr|  S t| jdkr6t| jdkr6|  S t| jtrJ| 	 S t| jt
jrt
jdd | jjjd| jd}W 5 Q R X | jj|dS | jdkr| | jS t| jjs|  S | jr|  S |  S )zcompute the resultsr   ignorer   rY   rp   datarH   )r!   rM   r   r   r   r|   apply_empty_resultrO   rR   r]   rP   rQ   errstater3   _mgrrY   _constructorr7   apply_broadcastr   shaper6   	apply_rawapply_standard)rT   r   rA   rA   rB   rY     s"    

zFrameApply.applyc              
     s   | j }| j}| jdkr| j n| j j| _ d| _d }zJzt  }W n6 tk
rv } ztd| }||W 5 d }~X Y nX W 5 || _ || _X |dkr|d k	r|jn|}|d kr| j j| j|fd| ji| j	}|S )Nr   z?DataFrame constructor called with incompatible data and dtype: r9   r;   )
r3   r5   ru   superrh   ry   rY   rS   r;   r<   )rT   r3   r5   r~   r   exc	__class__rA   rB   rh     s&     zFrameApply.aggc                 C  s   t | jst| jdkr"| j S | jdk}ddlm} |sz:| jdkr^| |g t	j
d}n| || jt	j
d}W n tk
r   Y nX t|| }|rt| jr| |g t	j
d}nt	j}| jj|| jdS | j S dS )	z
        we have an empty result; at least 1 axis is 0

        we will try to apply the function to an empty
        series in order to see if this is a reduction function
        )rG   NrG   r   r   dtype)r|   r   r|   N)r`   rM   rt   r7   r3   r   r   r,   r5   rP   float64r   rz   rO   r   r   nan_constructor_sliced)rT   Zshould_reducer,   r   rA   rA   rB   r     s&    




zFrameApply.apply_empty_resultc                 C  sV   dd }t || j| j| j}|jdkr@| jj|| j| j	dS | jj
|| jdS dS )z$apply to the values as a numpy arrayc                   s    fdd}|S )z
            Wrap user supplied function to work around numpy issue.

            see https://github.com/numpy/numpy/issues/8352
            c                    s&    | |}t |tr"tj|td}|S )Nr   )rO   rR   rP   arrayobject)r;   r<   r~   rp   rA   rB   wrapperM  s    

z<FrameApply.apply_raw.<locals>.wrap_function.<locals>.wrapperrA   )r4   r  rA   rp   rB   wrap_functionF  s    z+FrameApply.apply_raw.<locals>.wrap_functionr   r|   r   r   N)rP   Zapply_along_axisrM   r5   r   rs   r3   r   r|   r   r  r   )rT   r  r~   rA   rA   rB   r   C  s
    
zFrameApply.apply_rawtargetr8   c           	      C  s   t | jstt|j}|jd }t|jD ]`\}}| || }t	|j
}|dkrbtdn|dkr~|t|kr~td||d d |f< q.| jj||j|jd}|S )Nr   r9   ztoo many dims to broadcastzcannot broadcast resultr  )r`   rM   rt   rP   Z
empty_liker   r   r   r   Zasarrayrs   rN   r   r3   r   r|   )	rT   r  Zresult_valuesZresult_compareiro   resZaresr~   rA   rA   rB   r   ]  s$    

  zFrameApply.apply_broadcastc                 C  s   |   \}}| ||S rJ   )apply_series_generatorwrap_resultsr   rA   rA   rB   r   z  s    zFrameApply.apply_standardztuple[ResType, Index]c              	   C  s~   t | jst| j}| j}i }tdd H t|D ]8\}}| |||< t|| tr2|| j	dd||< q2W 5 Q R X ||fS )Nzmode.chained_assignmentF)deep)
r`   rM   rt   r   r   r   r   rO   r%   r   )rT   Z
series_genr   r   r	  rm   rA   rA   rB   r    s     z!FrameApply.apply_series_generatorc                 C  sj   ddl m} t|dkr8d|kr8t|d r8| ||S | jj}||krXt|tj	d}n||}||_
|S )Nr   r   )Zdtype_if_empty)r   r,   r   r"   r   r3   r  r(   rP   r   r|   )rT   r   r   r,   Zconstructor_slicedr~   rA   rA   rB   r    s      zFrameApply.wrap_resultsc                   s6   | j dkr,| j}|j| j }|j|| jdS t  S )Nr   r   )rM   r3   r   r5   r  r   r   r]   )rT   r3   valuer   rA   rB   r]     s
    
zFrameApply.apply_str)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rY   rh   r   r   r   r   r  r  r]   __classcell__rA   rA   r   rB   r2     s:   

#(c                      sj   e Zd ZdZddd fddZedd Zedd	d
dZedd	ddZddddddZ	  Z
S )r>   r   r*   r  c                   s   t  |S rJ   )r   r   )rT   r  r   rA   rB   r     s    zFrameRowApply.apply_broadcastc                   s    fddt t jD S )Nc                 3  s   | ]} j j|d dV  qdS )r9   r   N)r3   _ixs)rl   r	  rX   rA   rB   r     s     z1FrameRowApply.series_generator.<locals>.<genexpr>)ranger   r   rX   rA   rX   rB   r     s    zFrameRowApply.series_generatorr+   rW   c                 C  s   | j S rJ   r   rX   rA   rA   rB   r     s    zFrameRowApply.result_indexc                 C  s   | j S rJ   r   rX   rA   rA   rB   r     s    zFrameRowApply.result_columnsr   rV   r   c              
   C  s   | j dkr | j|}||_|S | j dkrVtdd | D rV| j|}||_|S z| jj|d}W nN tk
r } z0dt|kr| j|}||_| W Y S  W 5 d}~X Y nX t	|d t
st|jt| jkr| j|_t|jt|kr||_|S )zreturn the results for the rowsrG   Nc                 s  s   | ]}t |tV  qd S rJ   )rO   r   )rl   rK   rA   rA   rB   r     s    z6FrameRowApply.wrap_results_for_axis.<locals>.<genexpr>r   z%All arrays must be of the same lengthr   )r7   r3   r  r|   r   r   r   rN   rR   rO   r%   r   r   r   )rT   r   r   r
  r~   r   rA   rA   rB   r     s0    
z#FrameRowApply.wrap_results_for_axis)r   r   r   r5   r   r   r   r   r   r   r  rA   rA   r   rB   r>     s   
r>   c                      s|   e Zd ZdZddd fddZedd Zedd	d
dZedd	ddZddddddZ	ddddddZ
  ZS )r?   r9   r*   r  c                   s   t  |j}|jS rJ   )r   r   ru   )rT   r  r~   r   rA   rB   r     s    z FrameColumnApply.apply_broadcastc                 c  s   | j }t|}t|dkst| jjddd}|j}t|jrh| j}t	t|D ]}|j|ddV  qPn:t
|| jD ],\}}||_|| t|d| |V  qtd S )Nr   r   _name)r   r)   r   rt   r3   r  r   r    r   r  zipr|   Z
set_valuesr  __setattr__)rT   r   ZserZmgrr3   r	  Zarrr   rA   rA   rB   r     s    

z!FrameColumnApply.series_generatorr+   rW   c                 C  s   | j S rJ   r   rX   rA   rA   rB   r     s    zFrameColumnApply.result_indexc                 C  s   | j S rJ   r  rX   rA   rA   rB   r     s    zFrameColumnApply.result_columnsr   rV   r   c                 C  sJ   | j dkr| ||}n.t|d ts:| j|}||_n| ||}|S )z"return the results for the columnsrI   r   )r7   infer_to_same_shaperO   r%   r3   r  r|   rT   r   r   r~   rA   rA   rB   r     s    
z&FrameColumnApply.wrap_results_for_axisc                 C  s&   | j j|d}|j}||_| }|S )z7infer the results to the same shape as the input objectr   )r3   r   ru   r|   Zinfer_objectsr  rA   rA   rB   r  /  s
    z$FrameColumnApply.infer_to_same_shape)r   r   r   r5   r   r   r   r   r   r   r  r  rA   rA   r   rB   r?     s   
r?   c                      sl   e Zd ZU ded< dZddddd fdd	Zd
dddZ fddZddddZd
dddZ	  Z
S )SeriesApplyr,   r3   r   r   r0   rF   )r3   r4   convert_dtyper8   c                   s"   || _ t j||dd ||d d S NFr:   )r  r   rU   )rT   r3   r4   r  r;   r<   r   rA   rB   rU   A  s    zSeriesApply.__init__rV   rW   c                 C  sH   | j }t|dkr|  S t| jr,|  S t| jtr@|  S | 	 S )Nr   )
r3   r   r   r!   rM   r   rO   rR   r]   r   rT   r3   rA   rA   rB   rY   T  s    
zSeriesApply.applyc              
     sp   t   }|d krl| j}| j}t|s*t|dd  z| j|}W n$ t	t
tfk
rj   || j}Y nX |S )N_level)r   rh   rM   r<   r`   rt   popr3   rY   rN   r   ry   )rT   r~   rM   r<   r   rA   rB   rh   e  s    

zSeriesApply.aggc                 C  s"   | j }|j|j|jdj|ddS )N)r   r|   rY   method)r3   r   r   r|   __finalize__r  rA   rA   rB   r     s
     zSeriesApply.apply_empty_resultc              
   C  s   t t| j}| j}tjddh t|tjr@||W  5 Q R  S t|j	rdt
|jdrd|j|}n|tj}tj||| jd}W 5 Q R X t|rt|d tr|jt||jdS |j||jdj|ddS d S )	Nr   r   map)convertr   r   rY   r  )r   r   rM   r3   rP   r   rO   rQ   r    r   r   Z_valuesr!  Zastyper  r   Z	map_inferr  r   r%   Z_constructor_expanddimr   r|   r   r   )rT   rM   r3   Zmappedr   rA   rA   rB   r     s&     zSeriesApply.apply_standard)r   r   r   r   r5   rU   rY   rh   r   r   r  rA   rA   r   rB   r  =  s   
r  c                      s6   e Zd Zdddd fddZdd Zd	d
 Z  ZS )GroupByApplyzGroupBy[NDFrameT]r   rF   r3   r4   r8   c                   s:   |  }|j|dd| _t j||dd ||d d S )Nr5   r   Fr:   )r   r3   r=   getr5   r   rU   rT   r3   r4   r;   r<   r   rA   rB   rU     s    zGroupByApply.__init__c                 C  s   t d S rJ   r   rX   rA   rA   rB   rY     s    zGroupByApply.applyc                 C  s   t d S rJ   r'  rX   rA   rA   rB   rv     s    zGroupByApply.transform)r   r   r   rU   rY   rv   r  rA   rA   r   rB   r#    s   r#  c                      sD   e Zd ZU dZded< dddd fddZd	d
 Zdd Z  ZS )ResamplerWindowApplyr   zResampler | BaseWindowr3   r   rF   r$  c                   s   t  j||dd ||d d S r  )r   rU   r&  r   rA   rB   rU     s    zResamplerWindowApply.__init__c                 C  s   t d S rJ   r'  rX   rA   rA   rB   rY     s    zResamplerWindowApply.applyc                 C  s   t d S rJ   r'  rX   rA   rA   rB   rv     s    zResamplerWindowApply.transform)	r   r   r   r5   r   rU   rY   rv   r  rA   rA   r   rB   r(    s
   
r(  zAggFuncType | NonezNtuple[bool, AggFuncType | None, list[str] | None, npt.NDArray[np.intp] | None])r4   r8   c                 K  st   | dkot f |}d}d}|sVt| trFt| tt| krFtdn| dkrVtd|rht|\} }}|| ||fS )a  
    This is the internal function to reconstruct func given if there is relabeling
    or not and also normalize the keyword to get new order of columns.

    If named aggregation is applied, `func` will be None, and kwargs contains the
    column and aggregation function information to be parsed;
    If named aggregation is not applied, `func` is either string (e.g. 'min') or
    Callable, or list of them (e.g. ['min', np.max]), or the dictionary of column name
    and str/Callable/list of them (e.g. {'A': 'min'}, or {'A': [np.min, lambda x: x]})

    If relabeling is True, will return relabeling, reconstructed func, column
    names, and the reconstructed order of columns.
    If relabeling is False, the columns and order will be None.

    Parameters
    ----------
    func: agg function (e.g. 'min' or Callable) or list of agg functions
        (e.g. ['min', np.max]) or dictionary (e.g. {'A': ['min', np.max]}).
    **kwargs: dict, kwargs used in is_multi_agg_with_relabel and
        normalize_keyword_aggregation function for relabelling

    Returns
    -------
    relabelling: bool, if there is relabelling or not
    func: normalized and mangled func
    columns: list of column names
    order: array of columns indices

    Examples
    --------
    >>> reconstruct_func(None, **{"foo": ("col", "min")})
    (True, defaultdict(<class 'list'>, {'col': ['min']}), ('foo',), array([0]))

    >>> reconstruct_func("min")
    (False, 'min', None, None)
    NzFFunction names must be unique if there is no new column names assignedz4Must provide 'func' or tuples of '(column, aggfunc).)is_multi_agg_with_relabelrO   r   r   r   r   ry   normalize_keyword_aggregation)r4   r<   Z
relabelingr   orderrA   rA   rB   reconstruct_func  s    'r,  rW   c                  K  s"   t dd |  D o t| dkS )ax  
    Check whether kwargs passed to .agg look like multi-agg with relabeling.

    Parameters
    ----------
    **kwargs : dict

    Returns
    -------
    bool

    Examples
    --------
    >>> is_multi_agg_with_relabel(a="max")
    False
    >>> is_multi_agg_with_relabel(a_max=("a", "max"), a_min=("a", "min"))
    True
    >>> is_multi_agg_with_relabel()
    False
    c                 s  s$   | ]}t |tot|d kV  qdS )r   N)rO   r   r   rk   rA   rA   rB   r   .  s     z,is_multi_agg_with_relabel.<locals>.<genexpr>r   )r   r   r   )r<   rA   rA   rB   r)    s    
r)  r   z,tuple[dict, list[str], npt.NDArray[np.intp]])r<   r8   c                 C  s   ddl m} tt}g }tt|   \}}|D ].\}}|| | ||t|pX|f q0t	|}dd | D }	t	|	}
||

|}|||fS )aL  
    Normalize user-provided "named aggregation" kwargs.
    Transforms from the new ``Mapping[str, NamedAgg]`` style kwargs
    to the old Dict[str, List[scalar]]].

    Parameters
    ----------
    kwargs : dict

    Returns
    -------
    aggspec : dict
        The transformed kwargs.
    columns : List[str]
        The user-provided keys.
    col_idx_order : List[int]
        List of columns indices.

    Examples
    --------
    >>> normalize_keyword_aggregation({"output": ("input", "sum")})
    (defaultdict(<class 'list'>, {'input': ['sum']}), ('output',), array([0]))
    r   r   c                 S  s,   g | ]$\}}|D ]}|t |p"|fqqS rA   ri   )rl   columnaggfuncsaggfuncrA   rA   rB   r   b  s    z1normalize_keyword_aggregation.<locals>.<listcomp>)pandas.core.indexes.baser+   r   r   r  r   r   ra   rj   _make_unique_kwarg_listget_indexer)r<   r+   Zaggspecr+  r   pairsr-  r/  Zuniquified_orderZaggspec_orderZuniquified_aggspeccol_idx_orderrA   rA   rB   r*  3  s    r*  zSequence[tuple[Any, Any]])seqr8   c                   s    fddt  D S )a  
    Uniquify aggfunc name of the pairs in the order list

    Examples:
    --------
    >>> kwarg_list = [('a', '<lambda>'), ('a', '<lambda>'), ('b', '<lambda>')]
    >>> _make_unique_kwarg_list(kwarg_list)
    [('a', '<lambda>_0'), ('a', '<lambda>_1'), ('b', '<lambda>')]
    c              
     sN   g | ]F\}}  |d krF|d d|d  t d|  |gfn|qS )r9   r   r   N)countjoinrR   )rl   r	  pairr5  rA   rB   r   z  s   .z+_make_unique_kwarg_list.<locals>.<listcomp>)r   r9  rA   r9  rB   r1  n  s    
r1  rV   zdict[str, list[Callable | str]]zIterable[Hashable]zIterable[int]zdict[Hashable, Series])r~   r4   r   r+  r8   c                 C  s   ddl m} dd tt||dd dD }i }d}t| t oLt| jdk}| D ]r\}	}
| |	 	 }|rd	d |
D }
||j
|
}|| }|||t|
  |_
|j|d
d||	< |t|
 }qV|S )a  
    Internal function to reorder result if relabelling is True for
    dataframe.agg, and return the reordered result in dict.

    Parameters:
    ----------
    result: Result from aggregation
    func: Dict of (column name, funcs)
    columns: New columns name for relabelling
    order: New order for relabelling

    Examples:
    ---------
    >>> result = DataFrame({"A": [np.nan, 2, np.nan],
    ...       "C": [6, np.nan, np.nan], "B": [np.nan, 4, 2.5]})  # doctest: +SKIP
    >>> funcs = {"A": ["max"], "C": ["max"], "B": ["mean", "min"]}
    >>> columns = ("foo", "aab", "bar", "dat")
    >>> order = [0, 1, 2, 3]
    >>> _relabel_result(result, func, columns, order)  # doctest: +SKIP
    dict(A=Series([2.0, NaN, NaN, NaN], index=["foo", "aab", "bar", "dat"]),
         C=Series([NaN, 6.0, NaN, NaN], index=["foo", "aab", "bar", "dat"]),
         B=Series([NaN, NaN, 2.5, 4.0], index=["foo", "aab", "bar", "dat"]))
    r   r   c                 S  s   g | ]}|d  qS )r   rA   )rl   r8  rA   rA   rB   r     s    z"relabel_result.<locals>.<listcomp>c                 S  s   | d S )Nr9   rA   )trA   rA   rB   <lambda>      z relabel_result.<locals>.<lambda>)r   r9   c                 S  s$   g | ]}t |tst|n|qS rA   )rO   rR   ra   rj   )rl   rM   rA   rA   rB   r     s    Fr   )r0  r+   sortedr  rO   r%   r   r   r   Zdropnar|   r2  r   )r~   r4   r   r+  r+   Zreordered_indexesZreordered_result_in_dictidxZreorder_maskro   Zfunsr4  rA   rA   rB   relabel_result  s&    r@  zSequence[Any])r.  r8   c                 C  s\   t | dkr| S d}g }| D ]:}t|dkrLt|}d| d|_|d7 }|| q|S )aJ  
    Possibly mangle a list of aggfuncs.

    Parameters
    ----------
    aggfuncs : Sequence

    Returns
    -------
    mangled: list-like
        A new AggSpec sequence, where lambdas have been converted
        to have unique names.

    Notes
    -----
    If just one aggfunc is passed, the name will not be mangled.
    r9   r   z<lambda>z<lambda_>)r   ra   rj   r   r   r   )r.  r	  mangled_aggfuncsr/  rA   rA   rB   _managle_lambda_list  s    rC  r   )agg_specr8   c                 C  sl   t | }|st| s| S t|  }|r`|  D ].\}}t|rPt |sPt|}n|}|||< q.nt| }|S )aZ  
    Make new lambdas with unique names.

    Parameters
    ----------
    agg_spec : Any
        An argument to GroupBy.agg.
        Non-dict-like `agg_spec` are pass through as is.
        For dict-like `agg_spec` a new spec is returned
        with name-mangled lambdas.

    Returns
    -------
    mangled : Any
        Same type as the input.

    Examples
    --------
    >>> maybe_mangle_lambdas('sum')
    'sum'
    >>> maybe_mangle_lambdas([lambda: 1, lambda: 2])  # doctest: +SKIP
    [<function __main__.<lambda_0>,
     <function pandas...._make_lambda.<locals>.f(*args, **kwargs)>]
    )r   r!   r   r   rC  )rD  Zis_dictZmangled_aggspecr   r.  rB  rA   rA   rB   maybe_mangle_lambdas  s    

rE  z0tuple[list[str], list[str | Callable[..., Any]]]c                 C  sf   d}t | }g }|  D ]4}t|tsBt|sBt|t|j|	| q|s^d}t|||fS )a  
    Validates types of user-provided "named aggregation" kwargs.
    `TypeError` is raised if aggfunc is not `str` or callable.

    Parameters
    ----------
    kwargs : dict

    Returns
    -------
    columns : List[str]
        List of user-provied keys.
    func : List[Union[str, callable[...,Any]]]
        List of user-provided aggfuncs

    Examples
    --------
    >>> validate_func_kwargs({'one': 'min', 'two': 'max'})
    (['one', 'two'], ['min', 'max'])
    z-func is expected but received {} in **kwargs.z2Must provide 'func' or named aggregation **kwargs.)
r   r   rO   rR   r`   ry   r   r   r   r   )r<   Ztuple_given_messager   r4   Zcol_funcZno_arg_messagerA   rA   rB   validate_func_kwargs"  s    rF  )r   FNNN)`
__future__r   r   collectionsr   	functoolsr   r   r   typingr   r   r   r   r	   r
   r   r   r   r   r   r   ZnumpyrP   Zpandas._configr   Zpandas._libsr   Zpandas._typingr   r   r   r   r   r   r   Zpandas.errorsr   r   Zpandas.util._decoratorsr   Zpandas.util._exceptionsr   r   Zpandas.core.dtypes.castr   Zpandas.core.dtypes.commonr   r    r!   r"   Zpandas.core.dtypes.genericr#   r$   r%   Zpandas.core.algorithmsr&   Zpandas.core.baser'   Zpandas.core.commoncorecommonra   Zpandas.core.constructionr(   r)   r   r*   r+   r,   Zpandas.core.groupbyr-   Zpandas.core.resampler.   Zpandas.core.window.rollingr/   rE   r   rC   ABCMetarD   r   r2   r>   r?   r  r#  r(  r,  r)  r*  r1  r@  rC  rE  rF  rA   rA   rA   rB   <module>   sn   4$	         2  	<Li>;S!,