U
    sVc I                     @  s$  d Z ddlm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dddddddZdddddddZdddd Zddd!d"d#Zd$dd%d&Zddd!d'd(Zddd!d)d*Z dS )+zn
Methods that can be shared by many array-like classes or subclasses:
    Series
    Index
    ExtensionArray
    )annotationsN)Any)lib)!maybe_dispatch_ufunc_to_dunder_op)find_stack_level)
ABCNDFrame)	roperatorextract_array)unpack_zerodim_and_defermaxminsumprod)maximumZminimumadd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   9/tmp/pip-unpacked-wheel-xj8nt62q/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$   0   s    zOpsMixin.__lt____le__c                 C  s   |  |tjS r   )r   r   ler!   r   r   r   r&   4   s    zOpsMixin.__le____gt__c                 C  s   |  |tjS r   )r   r   gtr!   r   r   r   r(   8   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_methodC   s    zOpsMixin._logical_method__and__c                 C  s   |  |tjS r   )r,   r   and_r!   r   r   r   r-   F   s    zOpsMixin.__and____rand__c                 C  s   |  |tjS r   )r,   r   Zrand_r!   r   r   r   r/   J   s    zOpsMixin.__rand____or__c                 C  s   |  |tjS r   )r,   r   or_r!   r   r   r   r0   N   s    zOpsMixin.__or____ror__c                 C  s   |  |tjS r   )r,   r   Zror_r!   r   r   r   r2   R   s    zOpsMixin.__ror____xor__c                 C  s   |  |tjS r   )r,   r   xorr!   r   r   r   r3   V   s    zOpsMixin.__xor____rxor__c                 C  s   |  |tjS r   )r,   r   Zrxorr!   r   r   r   r5   Z   s    zOpsMixin.__rxor__c                 C  s   t S r   r   r   r   r   r   _arith_methoda   s    zOpsMixin._arith_method__add__c                 C  s   |  |tjS r   )r6   r   r   r!   r   r   r   r7   d   s    zOpsMixin.__add____radd__c                 C  s   |  |tjS r   )r6   r   Zraddr!   r   r   r   r8   h   s    zOpsMixin.__radd____sub__c                 C  s   |  |tjS r   )r6   r   subr!   r   r   r   r9   l   s    zOpsMixin.__sub____rsub__c                 C  s   |  |tjS r   )r6   r   Zrsubr!   r   r   r   r;   p   s    zOpsMixin.__rsub____mul__c                 C  s   |  |tjS r   )r6   r   mulr!   r   r   r   r<   t   s    zOpsMixin.__mul____rmul__c                 C  s   |  |tjS r   )r6   r   Zrmulr!   r   r   r   r>   x   s    zOpsMixin.__rmul____truediv__c                 C  s   |  |tjS r   )r6   r   truedivr!   r   r   r   r?   |   s    zOpsMixin.__truediv____rtruediv__c                 C  s   |  |tjS r   )r6   r   Zrtruedivr!   r   r   r   rA      s    zOpsMixin.__rtruediv____floordiv__c                 C  s   |  |tjS r   )r6   r   floordivr!   r   r   r   rB      s    zOpsMixin.__floordiv__Z__rfloordivc                 C  s   |  |tjS r   )r6   r   Z	rfloordivr!   r   r   r   __rfloordiv__   s    zOpsMixin.__rfloordiv____mod__c                 C  s   |  |tjS r   )r6   r   modr!   r   r   r   rE      s    zOpsMixin.__mod____rmod__c                 C  s   |  |tjS r   )r6   r   Zrmodr!   r   r   r   rG      s    zOpsMixin.__rmod__
__divmod__c                 C  s   |  |tS r   )r6   divmodr!   r   r   r   rH      s    zOpsMixin.__divmod____rdivmod__c                 C  s   |  |tjS r   )r6   r   Zrdivmodr!   r   r   r   rJ      s    zOpsMixin.__rdivmod____pow__c                 C  s   |  |tjS r   )r6   r   powr!   r   r   r   rK      s    zOpsMixin.__pow____rpow__c                 C  s   |  |tjS r   )r6   r   Zrpowr!   r   r   r   rM      s    zOpsMixin.__rpow__N)#__name__
__module____qualname__r   r   r   r"   r$   r&   r(   r*   r,   r-   r/   r0   r2   r3   r5   r6   r7   r8   r9   r;   r<   r>   r?   rA   rB   rD   rE   rG   rH   rJ   rK   rM   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)pandasrR   
isinstanceZ_indexed_samecolumnsequalsindex)framer   rR   r   r   r   _is_aligned   s    

rY   znp.ufuncstrr   )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 ]>}|kr|
| qt|r|
t| q|
| qt| |||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   rQ   NDFramec                 3  s   | ]}t | V  qd S r   rT   .0xr_   r   r   	<genexpr>   s     z"_maybe_fallback.<locals>.<genexpr>c                 3  s   | ]}t | V  qd S r   ra   rb   rQ   r   r   re      s           c                 3  s   | ]}t | r|V  qd S r   ra   rb   rQ   r   r   re      s     
 c                 3  s$   | ]}t | rt| V  qd S r   )rT   rY   rb   )r`   first_framer   r   re      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)rS   rR   pandas.core.genericr`   r   nextwarningswarnFutureWarningr   appendrT   npasarraygetattrr   )	r[   r\   r]   r^   Zn_alignableZn_framesZnon_aligned
new_inputsrd   r   )rR   r`   rh   r   _maybe_fallback   s0    

ru   c                   s6  ddl m ddlm  t}tf |}tf||}|tk	rH|S tf||}|tk	rh|S t	j
j|jf}|D ]P}t|do|jjk}	t|dot|j|kot|j }
|	s|
rzt  S qztdd |D }fdd	t||D td
krtt|d
kr$tdj}d
d D ]4}tt||jD ]\}\}}||||< qJq6ttj|tfddt||D }nttjjjd
krdd	 |D }tt|d
kr|d nd}d|ini fdd} fddd|kr@tf||}||S dkrltf||}|tk	rl|S jd
krt|d
ksjd
krtdd |D }t||}ntjd
krtdd |D }t||}nDdkr|s|d j }|!t}nt"|d f||}||}|S )z
    Compatibility with numpy ufuncs.

    See also
    --------
    numpy.org/doc/stable/reference/arrays.classes.html#numpy.class.__array_ufunc__
    r   r_   )BlockManager__array_priority____array_ufunc__c                 s  s   | ]}t |V  qd S r   )typerb   r   r   r   re   !  s     zarray_ufunc.<locals>.<genexpr>c                   s   g | ]\}}t | r|qS r   )
issubclassrc   rd   tr_   r   r   
<listcomp>"  s     
 zarray_ufunc.<locals>.<listcomp>rg   z;Cannot apply ufunc {} to mixed DataFrame and Series inputs.Nc                 3  s,   | ]$\}}t | r |jf n|V  qd S r   )rz   Zreindexr{   )r`   reconstruct_axesr   r   re   :  s   c                 S  s    g | ]}t |d rt|d qS )name)hasattrrs   rb   r   r   r   r}   B  s     
 r   c                   s(   j dkr t fdd| D S  | S )Nrg   c                 3  s   | ]} |V  qd S r   r   rb   )_reconstructr   r   re   K  s     z3array_ufunc.<locals>.reconstruct.<locals>.<genexpr>)nouttuple)result)r   r[   r   r   reconstructH  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	|  rvj
| fddi} nj
| fddi} tdkr| } | S )Nouterrf   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.ri   copyFrg   )r   Z	is_scalarndimrm   rn   formatro   r   NotImplementedErrorrT   Z_constructorlenZ__finalize__)r   msg)rv   	alignabler\   r~   reconstruct_kwargsr   r[   r   r   r   O  s8    

  
 
z!array_ufunc.<locals>._reconstructoutreducec                 s  s   | ]}t |V  qd S r   rq   rr   rb   r   r   r   re     s     c                 s  s   | ]}t |d dV  qdS )T)Zextract_numpyNr	   rb   r   r   r   re     s     __call__)#rk   r`   Zpandas.core.internalsrv   ry   _standardize_out_kwargru   r   r   rq   Zndarrayrx   r   rw   rT   Z_HANDLED_TYPESr   zipr   setr   r   axes	enumerateuniondictZ_AXIS_ORDERSr   dispatch_ufunc_with_outdispatch_reduction_ufuncr   rs   Z_mgrapplydefault_array_ufunc)r   r[   r\   r]   r^   clsr   Zno_deferitemZhigher_priorityZhas_array_ufunctypesr   objiZax1Zax2namesr   r   Zmgrr   )	rv   r`   r   r   r\   r~   r   r   r[   r   array_ufunc   s    






%


&	
r   r   )returnc                  K  s@   d| kr<d| kr<d| k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)r^   r   r   r   r   r   r   r     s    

r   )r[   r\   c           
      O  s   | d}| dd}t||||}|tkr2tS t|tr~t|trVt|t|krZtt||D ]\}}	t||	| qd|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   whereNrg   r   )	r   rs   r   rT   r   r   r   r   _assign_where)
r   r[   r\   r]   r^   r   r   r   Zarrresr   r   r   r     s"    



r   Nonec                 C  s(   |dkr|| dd< nt | || dS )zV
    Set a ufunc result into 'out', masking with a 'where' argument if necessary.
    N)rq   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||||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   | ]}| kV  qd S r   r   rb   r   r   r   re     s     z&default_array_ufunc.<locals>.<genexpr>c                   s"   g | ]}| k	r|nt |qS r   r   rb   r   r   r   r}     s     z'default_array_ufunc.<locals>.<listcomp>)anyr   rs   )r   r[   r\   r]   r^   rt   r   r   r   r     s    r   c                 O  s   |dkst t|dks$|d | k	r(tS |jtkr6tS t|j }t| |sNtS | jdkrzt| trjd|d< d|krzd|d< t	| |f ddi|S )z@
    Dispatch ufunc reductions to self's reduction methods.
    r   rg   r   FZnumeric_onlyZaxisZskipna)
AssertionErrorr   r   rN   REDUCTION_ALIASESr   r   rT   r   rs   )r   r[   r\   r]   r^   method_namer   r   r   r     s    




r   )!__doc__
__future__r   r   typingr   rm   Znumpyrq   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   rY   ru   r   r   r   r   r   r   r   r   r   r   <module>   s8    	> 2#