a
    GbH                     @   s"  d Z ddlZ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dddZG dd dZdd ZejeeedddZejeeedddZedddZejedddZdddd Zejedd!d"Z ejedd#d$Z!dS )%zn
Methods that can be shared by many array-like classes or subclasses:
    Series
    Index
    ExtensionArray
    N)Any)lib)!maybe_dispatch_ufunc_to_dunder_op)find_stack_level)
ABCNDFrame)	roperatorextract_array)unpack_zerodim_and_defermaxminsumZprod)ZmaximumZminimumaddZmultiplyc                   @   s  e Zd Zdd Zeddd Zeddd Zed	d
d Zeddd Zeddd Z	eddd Z
dd Zeddd Zeddd Zeddd Zed d!d" Zed#d$d% Zed&d'd( Zd)d* Zed+d,d- Zed.d/d0 Zed1d2d3 Zed4d5d6 Zed7d8d9 Zed:d;d< Zed=d>d? Zed@dAdB ZedCdDdE ZedFdGdH ZedIdJdK ZedLdMdN ZedOdPdQ ZedRdSdT Z edUdVdW Z!edXdYdZ Z"d[S )\OpsMixinc                 C   s   t S NNotImplementedselfotherop r   4lib/python3.9/site-packages/pandas/core/arraylike.py_cmp_method#   s    zOpsMixin._cmp_method__eq__c                 C   s   |  |tjS r   )r   operatoreqr   r   r   r   r   r   &   s    zOpsMixin.__eq____ne__c                 C   s   |  |tjS r   )r   r   ner   r   r   r   r   *   s    zOpsMixin.__ne____lt__c                 C   s   |  |tjS r   )r   r   ltr   r   r   r   r    .   s    zOpsMixin.__lt____le__c                 C   s   |  |tjS r   )r   r   ler   r   r   r   r"   2   s    zOpsMixin.__le____gt__c                 C   s   |  |tjS r   )r   r   gtr   r   r   r   r$   6   s    zOpsMixin.__gt____ge__c                 C   s   |  |tjS r   )r   r   ger   r   r   r   r&   :   s    zOpsMixin.__ge__c                 C   s   t S r   r   r   r   r   r   _logical_methodA   s    zOpsMixin._logical_method__and__c                 C   s   |  |tjS r   )r(   r   and_r   r   r   r   r)   D   s    zOpsMixin.__and____rand__c                 C   s   |  |tjS r   )r(   r   Zrand_r   r   r   r   r+   H   s    zOpsMixin.__rand____or__c                 C   s   |  |tjS r   )r(   r   or_r   r   r   r   r,   L   s    zOpsMixin.__or____ror__c                 C   s   |  |tjS r   )r(   r   Zror_r   r   r   r   r.   P   s    zOpsMixin.__ror____xor__c                 C   s   |  |tjS r   )r(   r   xorr   r   r   r   r/   T   s    zOpsMixin.__xor____rxor__c                 C   s   |  |tjS r   )r(   r   Zrxorr   r   r   r   r1   X   s    zOpsMixin.__rxor__c                 C   s   t S r   r   r   r   r   r   _arith_method_   s    zOpsMixin._arith_method__add__c                 C   s   |  |tjS r   )r2   r   r   r   r   r   r   r3   b   s    zOpsMixin.__add____radd__c                 C   s   |  |tjS r   )r2   r   Zraddr   r   r   r   r4   f   s    zOpsMixin.__radd____sub__c                 C   s   |  |tjS r   )r2   r   subr   r   r   r   r5   j   s    zOpsMixin.__sub____rsub__c                 C   s   |  |tjS r   )r2   r   Zrsubr   r   r   r   r7   n   s    zOpsMixin.__rsub____mul__c                 C   s   |  |tjS r   )r2   r   mulr   r   r   r   r8   r   s    zOpsMixin.__mul____rmul__c                 C   s   |  |tjS r   )r2   r   Zrmulr   r   r   r   r:   v   s    zOpsMixin.__rmul____truediv__c                 C   s   |  |tjS r   )r2   r   truedivr   r   r   r   r;   z   s    zOpsMixin.__truediv____rtruediv__c                 C   s   |  |tjS r   )r2   r   Zrtruedivr   r   r   r   r=   ~   s    zOpsMixin.__rtruediv____floordiv__c                 C   s   |  |tjS r   )r2   r   floordivr   r   r   r   r>      s    zOpsMixin.__floordiv__Z__rfloordivc                 C   s   |  |tjS r   )r2   r   Z	rfloordivr   r   r   r   __rfloordiv__   s    zOpsMixin.__rfloordiv____mod__c                 C   s   |  |tjS r   )r2   r   modr   r   r   r   rA      s    zOpsMixin.__mod____rmod__c                 C   s   |  |tjS r   )r2   r   Zrmodr   r   r   r   rC      s    zOpsMixin.__rmod__
__divmod__c                 C   s   |  |tS r   )r2   divmodr   r   r   r   rD      s    zOpsMixin.__divmod____rdivmod__c                 C   s   |  |tjS r   )r2   r   Zrdivmodr   r   r   r   rF      s    zOpsMixin.__rdivmod____pow__c                 C   s   |  |tjS r   )r2   r   powr   r   r   r   rG      s    zOpsMixin.__pow____rpow__c                 C   s   |  |tjS r   )r2   r   Zrpowr   r   r   r   rI      s    zOpsMixin.__rpow__N)#__name__
__module____qualname__r   r
   r   r   r    r"   r$   r&   r(   r)   r+   r,   r.   r/   r1   r2   r3   r4   r5   r7   r8   r:   r;   r=   r>   r@   rA   rC   rD   rF   rG   rI   r   r   r   r   r      sv   


























r   c                 C   s2   ddl m} t||r | |S | j|jS dS )zU
    Helper to check if a DataFrame is aligned with another DataFrame or Series.
    r   	DataFrameN)pandasrN   
isinstanceZ_indexed_samecolumnsZequalsindex)framer   rN   r   r   r   _is_aligned   s    

rT   )ufuncmethodinputskwargsc           	         s   ddl m  ddlm tfdd|D }t fdd|D }|dkr|dkrt fd	d|D tfd
d|D }|rtjdtt	 d g }|D ]>}|u r|
| qt|r|
t| q|
| qt| ||i |S tS )a  
    In the future DataFrame, inputs to ufuncs will be aligned before applying
    the ufunc, but for now we ignore the index but raise a warning if behaviour
    would change in the future.
    This helper detects the case where a warning is needed and then fallbacks
    to applying the ufunc on arrays to avoid alignment.

    See https://github.com/pandas-dev/pandas/pull/39239
    r   rM   NDFramec                 3   s   | ]}t | V  qd S r   rP   .0xrY   r   r   	<genexpr>       z"_maybe_fallback.<locals>.<genexpr>c                 3   s   | ]}t | V  qd S r   r[   r\   rM   r   r   r_      r`         c                 3   s   | ]}t | r|V  qd S r   r[   r\   rM   r   r   r_      r`   c                 3   s$   | ]}t | rt| V  qd S r   )rP   rT   r\   )rZ   first_framer   r   r_      s   a  Calling a ufunc on non-aligned DataFrames (or DataFrame/Series combination). Currently, the indices are ignored and the result takes the index/columns of the first DataFrame. In the future , the DataFrames/Series will be aligned before applying the ufunc.
Convert one of the arguments to a NumPy array (eg 'ufunc(df1, np.asarray(df2)') to keep the current behaviour, or align manually (eg 'df1, df2 = df1.align(df2)') before passing to the ufunc to obtain the future behaviour and silence this warning.
stacklevel)rO   rN   pandas.core.genericrZ   r   nextwarningswarnFutureWarningr   appendrP   npasarraygetattrr   )	rU   rV   rW   rX   Zn_alignableZn_framesZnon_aligned
new_inputsr^   r   )rN   rZ   rc   r   _maybe_fallback   s0    

rp   c                    s`  ddl m ddlm  t}tf i |}tg|R i |}|turR|S tg|R i |}|turx|S t	j
j|jf}|D ]P}t|do|jjk}	t|dot|j|vot|j }
|	s|
rt  S qtdd |D }fdd	t||D td
krtt|d
kr4tdj}d
d D ]4}tt||jD ]\}\}}||||< qZqFttj|tfddt||D }nttjjjd
kr dd	 |D }tt|d
kr|d nd}d|ini fdd} fddd|v rVtg|R i |}||S dkrtg|R i |}|tur|S jd
krt|d
ksjd
krtdd |D }t|i |}n~jd
kr
tdd |D }t|i |}nJdkr6|s6|d j }|!t}nt"|d g|R i |}||}|S )z
    Compatibility with numpy ufuncs.

    See also
    --------
    numpy.org/doc/stable/reference/arrays.classes.html#numpy.class.__array_ufunc__
    r   rY   )BlockManager__array_priority____array_ufunc__c                 s   s   | ]}t |V  qd S r   )typer\   r   r   r   r_     r`   zarray_ufunc.<locals>.<genexpr>c                    s   g | ]\}}t | r|qS r   )
issubclassr]   r^   trY   r   r   
<listcomp>  r`   zarray_ufunc.<locals>.<listcomp>rb   z;Cannot apply ufunc {} to mixed DataFrame and Series inputs.Nc                 3   s0   | ](\}}t | r$|jf i n|V  qd S r   )ru   Zreindexrv   )rZ   reconstruct_axesr   r   r_   5  s   c                 S   s    g | ]}t |d rt|d qS )name)hasattrrn   r\   r   r   r   rx   =  r`   rz   c                    s(   j dkr t fdd| D S  | S )Nrb   c                 3   s   | ]} |V  qd S r   r   r\   )_reconstructr   r   r_   F  r`   z3array_ufunc.<locals>.reconstruct.<locals>.<genexpr>)nouttuple)result)r|   rU   r   r   reconstructC  s    
z array_ufunc.<locals>.reconstructc                    s   t | r| S | jjkrTdkrPjdkrLd}tj|tt d | S t| S t	|  rzj
| fi ddi} nj
| fi ddi} tdkr| } | S )NZouterra   zouter method for ufunc {} is not implemented on pandas objects. Returning an ndarray, but in the future this will raise a 'NotImplementedError'. Consider explicitly converting the DataFrame to an array with '.to_numpy()' first.rd   copyFrb   )r   Z	is_scalarndimrh   ri   formatrj   r   NotImplementedErrorrP   Z_constructorlenZ__finalize__)r   msg)rq   	alignablerV   ry   reconstruct_kwargsr   rU   r   r   r|   J  s6    



z!array_ufunc.<locals>._reconstructoutreducec                 s   s   | ]}t |V  qd S r   rl   rm   r\   r   r   r   r_     r`   c                 s   s   | ]}t |d dV  qdS )T)Zextract_numpyNr   r\   r   r   r   r_     r`   __call__)#rf   rZ   Zpandas.core.internalsrq   rt   _standardize_out_kwargrp   r   r   rl   Zndarrayrs   r{   rr   rP   Z_HANDLED_TYPESr~   zipr   setr   r   axes	enumerateuniondictZ_AXIS_ORDERSr   dispatch_ufunc_with_outdispatch_reduction_ufuncr}   rn   Z_mgrZapplydefault_array_ufunc)r   rU   rV   rW   rX   clsr   Zno_deferitemZhigher_priorityZhas_array_ufunctypesr   objiZax1Zax2namesrz   r   Zmgrr   )	rq   rZ   r|   r   rV   ry   r   r   rU   r   array_ufunc   s    





%


&	
r   )returnc                  K   s@   d| vr<d| v r<d| v r<|  d}|  d}||f}|| d< | S )z
    If kwargs contain "out1" and "out2", replace that with a tuple "out"

    np.divmod, np.modf, np.frexp can have either `out=(out1, out2)` or
    `out1=out1, out2=out2)`
    r   out1out2)pop)rX   r   r   r   r   r   r   r     s    

r   )rU   rV   c           
      O   s   | d}| dd}t|||i |}|tu r6tS t|trt|trZt|t|kr^tt||D ]\}}	t||	| qh|S t|trt|dkr|d }ntt||| |S )zz
    If we have an `out` keyword, then call the ufunc without `out` and then
    set the result into the given `out`.
    r   whereNrb   r   )	r   rn   r   rP   r~   r   r   r   _assign_where)
r   rU   rV   rW   rX   r   r   r   Zarrresr   r   r   r     s"    



r   c                 C   s(   |du r|| dd< nt | || dS )zV
    Set a ufunc result into 'out', masking with a 'where' argument if necessary.
    N)rl   Zputmask)r   r   r   r   r   r   r     s    r   c                    s@   t  fdd|D st fdd|D }t|||i |S )z
    Fallback to the behavior we would get if we did not define __array_ufunc__.

    Notes
    -----
    We are assuming that `self` is among `inputs`.
    c                 3   s   | ]}| u V  qd S r   r   r\   r   r   r   r_     r`   z&default_array_ufunc.<locals>.<genexpr>c                    s"   g | ]}| ur|nt |qS r   r   r\   r   r   r   rx     r`   z'default_array_ufunc.<locals>.<listcomp>)anyr   rn   )r   rU   rV   rW   rX   ro   r   r   r   r     s    r   c                 O   s   |dksJ t |dks$|d | ur(tS |jtvr6tS t|j }t| |sNtS | jdkrzt| trjd|d< d|vrzd|d< t| |f ddi|S )z@
    Dispatch ufunc reductions to self's reduction methods.
    r   rb   r   FZnumeric_onlyZaxisZskipna)	r   r   rJ   REDUCTION_ALIASESr{   r   rP   r   rn   )r   rU   rV   rW   rX   method_namer   r   r   r     s    




r   )"__doc__r   typingr   rh   Znumpyrl   Zpandas._libsr   Zpandas._libs.ops_dispatchr   Zpandas.util._exceptionsr   Zpandas.core.dtypes.genericr   Zpandas.corer   Zpandas.core.constructionr	   Zpandas.core.ops.commonr
   r   r   rT   rU   strrp   r   r   r   r   r   r   r   r   r   r   r   <module>   s6    	> /#