U
    _{f                     @  s  d dl mZ d dlZd dlZd dlZd dlmZmZmZ d dl	Z	d dl
Zd dlmZ d dlmZmZmZmZ d dlmZmZmZmZmZmZmZmZm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(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ d d
l0m1Z1 d dl2m3Z3m4Z4m5Z5 d dl6m7Z7 edddZ8e8dk	Z9da:ddddddZ;e;ed G dd dZ<G dd dZ=dddddd Z>dd!d"d#Z?ddd$d%d&d'Z@d(dd)d)d*d+d,ZAdd(dd-d.d)d/d0d1d2ZBddd3d4d5ZCdd6d7d8d9ZDd:d:d;d<d=ZEd(d>d?d@dAdBZFd:d:d;dCdDZGddddEd(d>dd)ddFdGdHZHddddEd(d>dd)ddFdIdJZIe<dKeEeGddd ddLd(d>ddMd)dNdOdPdQZJdRd>dSd(dTdUdVdWZKe<e1e= eEddddEd(d>dd)dNdFdXdYZLe= ddddEd>ddZd[d\ZMd]d^d_d-d(d`dadbZNeOejPfdcd)d>dMd6dddedfdgZQe=dhdidddhddjd>ddMdkdldmZRe<dKdne=dhdidddhddjd>ddMdkdodpZSe<dKdndddhddjd(d>ddMd)dNdqdrdsZTdtdu ZUeUdvdwdxZVeUdydzdxZWe<d{ddddEd(d>dd)d|dFd}d~ZXe<d{ddddEd(d>dd)d|dFddZYe<dKdneGddddEd(d>dd)dNdFddZZe<dKdneGddddEd(d>dd)dNdFddZ[e<dKdneGddd ddLd(d>ddMd)dNdOddZ\d(d>d)dddddZ]eOejPfdcd)d>d6ddddZ^ddd>d)d]dMddddZ_d]d)dMddddZ`dd Zae<dKdndddd(d(dddNdddZbdddddZce<dKdnddhdd(d(dddNdddZddd Zedd ZfefejgZhefejiZjefejkZlefejmZnefejoZpefejqZrddddddZsdS )    )annotationsN)AnyCallablecast)
get_option)NaTNaTTypeiNaTlib)		ArrayLikeAxisIntCorrelationMethodDtypeDtypeObjFScalarShapenpt)import_optional_dependency)find_stack_level)is_any_int_dtypeis_bool_dtype
is_complexis_datetime64_any_dtypeis_floatis_float_dtype
is_integeris_integer_dtypeis_numeric_dtypeis_object_dtype	is_scalaris_timedelta64_dtypeneeds_i8_conversionpandas_dtype)PeriodDtype)isnana_value_for_dtypenotna)extract_arrayZ
bottleneckwarn)errorsFTboolNone)vreturnc                 C  s   t r| ad S N)_BOTTLENECK_INSTALLED_USE_BOTTLENECK)r-    r2   Q/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/pandas/core/nanops.pyset_use_bottleneckC   s    r4   zcompute.use_bottleneckc                      sB   e Zd Zddd fddZdddd	Zd
d
dddZ  ZS )disallowr   r,   )dtypesr.   c                   s"   t    tdd |D | _d S )Nc                 s  s   | ]}t |jV  qd S r/   )r#   type).0dtyper2   r2   r3   	<genexpr>P   s     z$disallow.__init__.<locals>.<genexpr>)super__init__tupler6   )selfr6   	__class__r2   r3   r<   N   s    
zdisallow.__init__r+   r.   c                 C  s   t |dot|jj| jS )Nr9   )hasattr
issubclassr9   r7   r6   )r>   objr2   r2   r3   checkR   s    zdisallow.checkr   )fr.   c                   s"   t   fdd}tt|S )Nc               
     s   t | | }tfdd|D rD jdd}td| dz0tjdd  | |W  5 Q R  W S Q R X W n: t	k
r } zt
| d	 rt|| W 5 d }~X Y nX d S )
Nc                 3  s   | ]}  |V  qd S r/   )rE   )r8   rD   )r>   r2   r3   r:   Y   s     z0disallow.__call__.<locals>._f.<locals>.<genexpr>nan zreduction operation 'z' not allowed for this dtypeignoreinvalidr   )	itertoolschainvaluesany__name__replace	TypeErrornperrstate
ValueErrorr   )argskwargsZobj_iterf_nameerF   r>   r2   r3   _fV   s    
"
zdisallow.__call__.<locals>._f	functoolswrapsr   r   )r>   rF   r[   r2   rZ   r3   __call__U   s    zdisallow.__call__)rP   
__module____qualname__r<   rE   r_   __classcell__r2   r2   r?   r3   r5   M   s   r5   c                   @  s,   e Zd Zd
ddddZddddd	ZdS )bottleneck_switchNr,   rA   c                 K  s   || _ || _d S r/   )namerW   )r>   rd   rW   r2   r2   r3   r<   n   s    zbottleneck_switch.__init__r   )altr.   c              	     sp   j p
 jzttW n ttfk
r6   d Y nX t d dddddd fdd}tt	|S )	NTaxisskipna
np.ndarrayAxisInt | Noner+   )rN   rg   rh   c                  s   t jdkr2j D ]\}}||kr|||< q| jdkrT|dd krTt| |S tr|rt| jr|dd d kr|	dd  | fd|i|}t
|rΈ | f||d|}q | f||d|}n | f||d|}|S )Nr   	min_countmaskrg   rf   )lenrW   itemssizeget_na_for_min_countr1   _bn_ok_dtyper9   pop	_has_infs)rN   rg   rh   kwdskr-   resultre   Zbn_funcZbn_namer>   r2   r3   rF   z   s    

z%bottleneck_switch.__call__.<locals>.f)
rd   rP   getattrbnAttributeError	NameErrorr]   r^   r   r   )r>   re   rF   r2   rx   r3   r_   r   s    
"'zbottleneck_switch.__call__)N)rP   r`   ra   r<   r_   r2   r2   r2   r3   rc   m   s   rc   r   str)r9   rd   r.   c                 C  s   t | st| s|dkS dS )N)nansumnanprodnanmeanF)r   r"   )r9   rd   r2   r2   r3   rr      s    rr   rA   c              	   C  sV   t | tjr&| jdkr&t| dS zt|  W S  t	t
fk
rP   Y dS X d S )N)f8Zf4KF)
isinstancerS   ndarrayr9   r
   Zhas_infsZravelisinfrO   rR   NotImplementedError)rw   r2   r2   r3   rt      s    
rt   zScalar | None)r9   
fill_valuec                 C  sP   |dk	r|S t | r:|dkr"tjS |dkr0tjS tj S n|dkrHtjS tS dS )z9return the correct fill value for the dtype of the valuesN+inf)_na_ok_dtyperS   rG   infr
   i8maxr	   )r9   r   fill_value_typr2   r2   r3   _get_fill_value   s    
r   ri   npt.NDArray[np.bool_] | None)rN   rh   rl   r.   c                 C  s:   |dkr6t | jst| jr dS |s.t| jr6t| }|S )a  
    Compute a mask if and only if necessary.

    This function will compute a mask iff it is necessary. Otherwise,
    return the provided mask (potentially None) when a mask does not need to be
    computed.

    A mask is never necessary if the values array is of boolean or integer
    dtypes, as these are incapable of storing NaNs. If passing a NaN-capable
    dtype that is interpretable as either boolean or integer data (eg,
    timedelta64), a mask must be provided.

    If the skipna parameter is False, a new mask will not be computed.

    The mask is computed using isna() by default. Setting invert=True selects
    notna() as the masking function.

    Parameters
    ----------
    values : ndarray
        input array to potentially compute mask for
    skipna : bool
        boolean for whether NaNs should be skipped
    mask : Optional[ndarray]
        nan-mask if known

    Returns
    -------
    Optional[np.ndarray[bool]]
    N)r   r9   r   r"   r%   )rN   rh   rl   r2   r2   r3   _maybe_get_mask   s    !r   r   z
str | NonezHtuple[np.ndarray, npt.NDArray[np.bool_] | None, np.dtype, np.dtype, Any])rN   rh   r   r   rl   r.   c           	      C  s   t |stt| dd} t| ||}| j}d}t| jrLt| d} d}t	|}t
|||d}|r|dk	r|dk	r| r|s|r|  } t| || nt| | |} |}t|st|rttj}nt|rttj}| ||||fS )a7  
    Utility to get the values view, mask, dtype, dtype_max, and fill_value.

    If both mask and fill_value/fill_value_typ are not None and skipna is True,
    the values array will be copied.

    For input arrays of boolean or integer dtypes, copies will only occur if a
    precomputed mask, a fill_value/fill_value_typ, and skipna=True are
    provided.

    Parameters
    ----------
    values : ndarray
        input array to potentially compute mask for
    skipna : bool
        boolean for whether NaNs should be skipped
    fill_value : Any
        value to fill NaNs with
    fill_value_typ : str
        Set to '+inf' or '-inf' to handle dtype-specific infinities
    mask : Optional[np.ndarray[bool]]
        nan-mask if known

    Returns
    -------
    values : ndarray
        Potential copy of input value array
    mask : Optional[ndarray[bool]]
        Mask for values, if deemed necessary to compute
    dtype : np.dtype
        dtype for values
    dtype_max : np.dtype
        platform independent dtype
    fill_value : Any
        fill value used
    TZextract_numpyFi8)r   r   N)r    AssertionErrorr(   r   r9   r"   rS   Zasarrayviewr   r   rO   copyputmaskwherer   r   int64r   float64)	rN   rh   r   r   rl   r9   datetimelikeZdtype_ok	dtype_maxr2   r2   r3   _get_values  s4    .
  r   )r9   r.   c                 C  s   t | rdS t| jtj S )NF)r"   rC   r7   rS   integerr9   r2   r2   r3   r   a  s    r   znp.dtyper   c                 C  s  | t krn t|r|dkr t}t| tjst|r<td| |krJtj} t| rft	dd
|} nt| |} | j
|dd} n
| 
|} nzt|rt| tjs| |kst| rtd
|} n.t| tjkrtdnt| j
|dd} n| 
d|} | S )	zwrap our results if neededNzExpected non-null fill_valuer   nsFr   zoverflow in timedelta operationm8[ns])r   r   r	   r   rS   r   r%   r   rG   Z
datetime64astyper   r   r!   isnanZtimedelta64fabsr
   r   rU   )rw   r9   r   r2   r2   r3   _wrap_resultsg  s.    

r   r   )funcr.   c                   s6   t  ddddddddd fd	d
}tt|S )z
    If we have datetime64 or timedelta64 values, ensure we have a correct
    mask before calling the wrapped function, then cast back afterwards.
    NTrg   rh   rl   ri   rj   r+   r   )rN   rg   rh   rl   c                  sr   | }| j jdk}|r$|d kr$t| } | f|||d|}|rnt||j td}|sn|d k	s`tt||||}|S )NmMr   )r   )r9   kindr%   r   r	   r   _mask_datetimelike_result)rN   rg   rh   rl   rW   orig_valuesr   rw   r   r2   r3   new_func  s    	z&_datetimelike_compat.<locals>.new_funcr\   )r   r   r2   r   r3   _datetimelike_compat  s    r   rj   zScalar | np.ndarray)rN   rg   r.   c                 C  sl   t | r| d} t| j}| jdkr*|S |dkr6|S | jd| | j|d d  }tj||| jdS dS )a  
    Return the missing value for `values`.

    Parameters
    ----------
    values : ndarray
    axis : int or None
        axis for the reduction, required if values.ndim > 1.

    Returns
    -------
    result : scalar or ndarray
        For 1-D values, returns a scalar of the correct missing type.
        For 2-D values, returns a 1-D array where each element is missing.
    r      Nr   )r   r   r&   r9   ndimshaperS   full)rN   rg   r   Zresult_shaper2   r2   r3   rq     s    


 rq   c                   s.   t  ddddd fdd}tt|S )z
    NumPy operations on C-contiguous ndarrays with axis=1 can be
    very slow if axis 1 >> axis 0.
    Operate row-by-row and concatenate the results.
    Nrg   ri   rj   )rN   rg   c                  s   |dkr| j dkr| jd r| jd d | jd kr| jtkr| jtkrt|  dd k	rd fddt	t
 D }nfd	d D }t|S | fd
|iS )Nr      ZC_CONTIGUOUSi  r   rl   c                   s(   g | ] } | fd | iqS rl   r2   )r8   i)arrsr   rW   rl   r2   r3   
<listcomp>  s    z:maybe_operate_rowwise.<locals>.newfunc.<locals>.<listcomp>c                   s   g | ]} |fqS r2   r2   )r8   x)r   rW   r2   r3   r     s     rg   )r   flagsr   r9   objectr+   listrp   rs   rangerm   rS   array)rN   rg   rW   resultsr   )r   rW   rl   r3   newfunc  s*    



z&maybe_operate_rowwise.<locals>.newfuncr\   )r   r   r2   r   r3   maybe_operate_rowwise  s    r   r   rN   rg   rh   rl   r.   c                C  s^   t | jr(| jjdkr(tjdtt d t| |d|d\} }}}}t| rT| 	t
} | |S )a  
    Check if any elements along an axis evaluate to True.

    Parameters
    ----------
    values : ndarray
    axis : int, optional
    skipna : bool, default True
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    result : bool

    Examples
    --------
    >>> from pandas.core import nanops
    >>> s = pd.Series([1, 2])
    >>> nanops.nanany(s)
    True

    >>> from pandas.core import nanops
    >>> s = pd.Series([np.nan])
    >>> nanops.nanany(s)
    False
    r   zz'any' with datetime64 dtypes is deprecated and will raise in a future version. Use (obj != pd.Timestamp(0)).any() instead.
stacklevelFr   rl   )r"   r9   r   warningsr)   FutureWarningr   r   r   r   r+   rO   rN   rg   rh   rl   _r2   r2   r3   nanany  s    "
r   c                C  s^   t | jr(| jjdkr(tjdtt d t| |d|d\} }}}}t| rT| 	t
} | |S )a  
    Check if all elements along an axis evaluate to True.

    Parameters
    ----------
    values : ndarray
    axis : int, optional
    skipna : bool, default True
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    result : bool

    Examples
    --------
    >>> from pandas.core import nanops
    >>> s = pd.Series([1, 2, np.nan])
    >>> nanops.nanall(s)
    True

    >>> from pandas.core import nanops
    >>> s = pd.Series([1, 0])
    >>> nanops.nanall(s)
    False
    r   zz'all' with datetime64 dtypes is deprecated and will raise in a future version. Use (obj != pd.Timestamp(0)).all() instead.r   Tr   )r"   r9   r   r   r)   r   r   r   r   r   r+   allr   r2   r2   r3   nanall*  s    "
r   ZM8)rg   rh   rk   rl   intfloat)rN   rg   rh   rk   rl   r.   c          
      C  sf   t | |d|d\} }}}}|}t|r,|}nt|r@ttj}| j||d}	t|	||| j|d}	|	S )a  
    Sum the elements along an axis ignoring NaNs

    Parameters
    ----------
    values : ndarray[dtype]
    axis : int, optional
    skipna : bool, default True
    min_count: int, default 0
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    result : dtype

    Examples
    --------
    >>> from pandas.core import nanops
    >>> s = pd.Series([1, 2, np.nan])
    >>> nanops.nansum(s)
    3.0
    r   r   r   rk   )	r   r   r!   rS   r9   r   sum_maybe_null_outr   )
rN   rg   rh   rk   rl   r9   r   r   	dtype_sumthe_sumr2   r2   r3   r~   a  s    "   r~   z+np.ndarray | np.datetime64 | np.timedelta64znpt.NDArray[np.bool_]z5np.ndarray | np.datetime64 | np.timedelta64 | NaTType)rw   rg   rl   r   r.   c                 C  sR   t | tjr4| d|j} |j|d}t| |< n| rNtt|jS | S )Nr   r   )	r   rS   r   r   r   r9   rO   r	   r   )rw   rg   rl   r   Z	axis_maskr2   r2   r3   r     s    
r   c             	   C  s  t | |d|d\} }}}}|}ttj}|jdkrBttj}n&t|rXttj}nt|rh|}|}t| j|||d}	t	| j
||d}
|dk	rt|
ddrttj|	}	tjdd	 |
|	 }W 5 Q R X |	dk}| rtj||< n|	dkr|
|	 ntj}|S )
a  
    Compute the mean of the element along an axis ignoring NaNs

    Parameters
    ----------
    values : ndarray
    axis : int, optional
    skipna : bool, default True
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    float
        Unless input is a float array, in which case use the same
        precision as the input array.

    Examples
    --------
    >>> from pandas.core import nanops
    >>> s = pd.Series([1, 2, np.nan])
    >>> nanops.nanmean(s)
    1.5
    r   r   r   r   Nr   FrI   r   )r   rS   r9   r   r   r   r   _get_countsr   _ensure_numericr   ry   r   r   rT   rO   rG   )rN   rg   rh   rl   r9   r   r   r   Zdtype_countcountr   Zthe_meanZct_maskr2   r2   r3   r     s4    "   
r   rf   c          
   
     s  d
 fdd	}t |  |dd\} }}}}t| jsrz| d} W n0 tk
rp } ztt||W 5 d}~X Y nX |dk	rtj| |< | j	}| j
dkr|dk	r|r st||| }	qt   tdd	t t| |}	W 5 Q R X nt| j|tjtj}	n|r
|| |ntj}	t|	|S )a  
    Parameters
    ----------
    values : ndarray
    axis : int, optional
    skipna : bool, default True
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    result : float
        Unless input is a float array, in which case use the same
        precision as the input array.

    Examples
    --------
    >>> from pandas.core import nanops
    >>> s = pd.Series([1, np.nan, 2, 2])
    >>> nanops.nanmedian(s)
    2.0
    Nc              	     s^   |d krt | }n| } s*| s*tjS t " tddt t| | }W 5 Q R X |S )NrI   All-NaN slice encountered)	r'   r   rS   rG   r   catch_warningsfilterwarningsRuntimeWarning	nanmedian)r   Z_maskresrh   r2   r3   
get_median   s    

  znanmedian.<locals>.get_medianr   )rl   r   r   r   rI   r   )N)r   r   r9   r   rU   rR   r}   rS   rG   ro   r   Zapply_along_axisr   r   r   r   r   get_empty_reduction_resultr   Zfloat_r   )
rN   rg   rh   rl   r   r9   r   errZnotemptyr   r2   r   r3   r     s0    
 

  r   ztuple[int, ...]r   znp.dtype | type[np.floating])r   rg   r9   r   r.   c                 C  s<   t | }t t| }t j|||k |d}|| |S )z
    The result from a reduction on an empty ndarray.

    Parameters
    ----------
    shape : Tuple[int]
    axis : int
    dtype : np.dtype
    fill_value : Any

    Returns
    -------
    np.ndarray
    r   )rS   r   Zarangerm   emptyfill)r   rg   r9   r   ZshpZdimsretr2   r2   r3   r   8  s
    

r   r   z-tuple[float | np.ndarray, float | np.ndarray])values_shaperl   rg   ddofr9   r.   c                 C  s   t | |||d}||| }t|r<||krxtj}tj}n<ttj|}||k}| rxt||tj t||tj ||fS )a:  
    Get the count of non-null values along an axis, accounting
    for degrees of freedom.

    Parameters
    ----------
    values_shape : Tuple[int, ...]
        shape tuple from values ndarray, used if mask is None
    mask : Optional[ndarray[bool]]
        locations in values that should be considered missing
    axis : Optional[int]
        axis to count along
    ddof : int
        degrees of freedom
    dtype : type, optional
        type to use for count

    Returns
    -------
    count : int, np.nan or np.ndarray
    d : int, np.nan or np.ndarray
    r   )	r   r7   r    rS   rG   r   r   rO   r   )r   rl   rg   r   r9   r   dr2   r2   r3   _get_counts_nanvarS  s    r   r   r   rg   rh   r   rl   )rg   rh   r   c             	   C  sT   | j dkr| d} | j }t| ||d\} }}}}tt| ||||d}t||S )a  
    Compute the standard deviation along given axis while ignoring NaNs

    Parameters
    ----------
    values : ndarray
    axis : int, optional
    skipna : bool, default True
    ddof : int, default 1
        Delta Degrees of Freedom. The divisor used in calculations is N - ddof,
        where N represents the number of elements.
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    result : float
        Unless input is a float array, in which case use the same
        precision as the input array.

    Examples
    --------
    >>> from pandas.core import nanops
    >>> s = pd.Series([1, np.nan, 2, 3])
    >>> nanops.nanstd(s)
    1.0
    zM8[ns]r   r   r   )r9   r   r   rS   sqrtnanvarr   )rN   rg   rh   r   rl   Z
orig_dtyper   rw   r2   r2   r3   nanstd  s    $

r   Zm8c                C  s  t | dd} | j}t| ||}t|rB| d} |dk	rBtj| |< t| jrft| j	|||| j\}}nt| j	|||\}}|r|dk	r| 
 } t| |d t| j|tjd| }|dk	rt||}t||  d }	|dk	rt|	|d |	j|tjd| }
t|r|
j|dd	}
|
S )
a  
    Compute the variance along given axis while ignoring NaNs

    Parameters
    ----------
    values : ndarray
    axis : int, optional
    skipna : bool, default True
    ddof : int, default 1
        Delta Degrees of Freedom. The divisor used in calculations is N - ddof,
        where N represents the number of elements.
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    result : float
        Unless input is a float array, in which case use the same
        precision as the input array.

    Examples
    --------
    >>> from pandas.core import nanops
    >>> s = pd.Series([1, np.nan, 2, 3])
    >>> nanops.nanvar(s)
    1.0
    Tr   r   Nr   )rg   r9   r   Fr   )r(   r9   r   r   r   rS   rG   r   r   r   r   r   r   r   r   expand_dims)rN   rg   rh   r   rl   r9   r   r   avgZsqrrw   r2   r2   r3   r     s.    %



r   )rN   rg   rh   r   rl   r.   c                C  s   t | ||||d t| ||}t| js2| d} |sL|dk	rL| rLtjS t| j	|||| j\}}t | ||||d}t
|t
| S )a  
    Compute the standard error in the mean along given axis while ignoring NaNs

    Parameters
    ----------
    values : ndarray
    axis : int, optional
    skipna : bool, default True
    ddof : int, default 1
        Delta Degrees of Freedom. The divisor used in calculations is N - ddof,
        where N represents the number of elements.
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    result : float64
        Unless input is a float array, in which case use the same
        precision as the input array.

    Examples
    --------
    >>> from pandas.core import nanops
    >>> s = pd.Series([1, np.nan, 2, 3])
    >>> nanops.nansem(s)
     0.5773502691896258
    r   r   N)r   r   r   r9   r   rO   rS   rG   r   r   r   )rN   rg   rh   r   rl   r   r   varr2   r2   r3   nansem  s    &

r   c              	     s>   t d dtd dd dddddd	d
 fdd}|S )NrG   )rd   Tr   ri   rj   r+   r   r   r   c             
     s   t | | |d\} }}}}|d k	r0| j| dks:| jdkrz"t| ||d}|tj W q ttt	fk
r|   tj}Y qX nt| |}t
|||| j}|S )Nr   rl   r   r   )r   r   ro   ry   r   rS   rG   r{   rR   rU   r   )rN   rg   rh   rl   r9   r   r   rw   r   methr2   r3   	reduction2  s    	    z_nanminmax.<locals>.reduction)rc   r   )r   r   r   r2   r   r3   
_nanminmax1  s    $r   minr   )r   max-infOzint | np.ndarrayc                C  s6   t | dd|d\} }}}}| |}t||||}|S )a  
    Parameters
    ----------
    values : ndarray
    axis : int, optional
    skipna : bool, default True
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    result : int or ndarray[int]
        The index/indices  of max value in specified axis or -1 in the NA case

    Examples
    --------
    >>> from pandas.core import nanops
    >>> arr = np.array([1, 2, 3, np.nan, 4])
    >>> nanops.nanargmax(arr)
    4

    >>> arr = np.array(range(12), dtype=np.float64).reshape(4, 3)
    >>> arr[2:, 2] = np.nan
    >>> arr
    array([[ 0.,  1.,  2.],
           [ 3.,  4.,  5.],
           [ 6.,  7., nan],
           [ 9., 10., nan]])
    >>> nanops.nanargmax(arr, axis=1)
    array([2, 2, 1, 1])
    Tr   r   )r   Zargmax_maybe_arg_null_outrN   rg   rh   rl   r   rw   r2   r2   r3   	nanargmaxR  s    '
r   c                C  s6   t | dd|d\} }}}}| |}t||||}|S )a  
    Parameters
    ----------
    values : ndarray
    axis : int, optional
    skipna : bool, default True
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    result : int or ndarray[int]
        The index/indices of min value in specified axis or -1 in the NA case

    Examples
    --------
    >>> from pandas.core import nanops
    >>> arr = np.array([1, 2, 3, np.nan, 4])
    >>> nanops.nanargmin(arr)
    0

    >>> arr = np.array(range(12), dtype=np.float64).reshape(4, 3)
    >>> arr[2:, 0] = np.nan
    >>> arr
    array([[ 0.,  1.,  2.],
           [ 3.,  4.,  5.],
           [nan,  7.,  8.],
           [nan, 10., 11.]])
    >>> nanops.nanargmin(arr, axis=1)
    array([0, 0, 1, 1])
    Tr   r   )r   Zargminr   r   r2   r2   r3   	nanargmin  s    '
r   c             	   C  s  t | dd} t| ||}t| js<| d} t| j||}nt| j||| jd}|rt|dk	rt|  } t	| |d n|s|dk	r|
 rtjS | j|tjd| }|dk	rt||}| | }|r|dk	rt	||d |d }|| }|j|tjd}	|j|tjd}
t|	}	t|
}
tjddd	* ||d
 d  |d  |
|	d   }W 5 Q R X | j}t|rt|j|dd}t|tjrt|	dkd|}tj||dk < n"|	dkrdn|}|dk rtjS |S )a  
    Compute the sample skewness.

    The statistic computed here is the adjusted Fisher-Pearson standardized
    moment coefficient G1. The algorithm computes this coefficient directly
    from the second and third central moment.

    Parameters
    ----------
    values : ndarray
    axis : int, optional
    skipna : bool, default True
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    result : float64
        Unless input is a float array, in which case use the same
        precision as the input array.

    Examples
    --------
    >>> from pandas.core import nanops
    >>> s = pd.Series([1, np.nan, 1, 2])
    >>> nanops.nanskew(s)
    1.7320508075688787
    Tr   r   r   Nr   r   rI   rK   divider   g      ?g      ?Fr      )r(   r   r   r9   r   r   r   r   rS   r   rO   rG   r   r   r   _zero_out_fperrrT   r   r   r   )rN   rg   rh   rl   r   meanadjusted	adjusted2Z	adjusted3m2Zm3rw   r9   r2   r2   r3   nanskew  sF    '

.

r  c             	   C  s$  t | dd} t| ||}t| js<| d} t| j||}nt| j||| jd}|rt|dk	rt|  } t	| |d n|s|dk	r|
 rtjS | j|tjd| }|dk	rt||}| | }|r|dk	rt	||d |d }|d }|j|tjd}	|j|tjd}
tjddd	V d
|d d  |d |d
   }||d  |d  |
 }|d |d
  |	d  }W 5 Q R X t|}t|}t|tjs|dk rtjS |dkrdS tjddd	 || | }W 5 Q R X | j}t|r|j|dd}t|tjr t|dkd|}tj||dk < |S )a  
    Compute the sample excess kurtosis

    The statistic computed here is the adjusted Fisher-Pearson standardized
    moment coefficient G2, computed directly from the second and fourth
    central moment.

    Parameters
    ----------
    values : ndarray
    axis : int, optional
    skipna : bool, default True
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    result : float64
        Unless input is a float array, in which case use the same
        precision as the input array.

    Examples
    --------
    >>> from pandas.core import nanops
    >>> s = pd.Series([1, np.nan, 1, 3, 2])
    >>> nanops.nankurt(s)
    -1.2892561983471076
    Tr   r   r   Nr   r   rI   r   r  r      Fr   )r(   r   r   r9   r   r   r   r   rS   r   rO   rG   r   r   r   rT   r  r   r   r   )rN   rg   rh   rl   r   r  r  r  Z	adjusted4r  Zm4Zadj	numeratordenominatorrw   r9   r2   r2   r3   nankurt  sR    '

 "


r  c                C  sF   t | ||}|r(|dk	r(|  } d| |< | |}t|||| j|dS )a  
    Parameters
    ----------
    values : ndarray[dtype]
    axis : int, optional
    skipna : bool, default True
    min_count: int, default 0
    mask : ndarray[bool], optional
        nan-mask if known

    Returns
    -------
    Dtype
        The product of all elements on a given axis. ( NaNs are treated as 1)

    Examples
    --------
    >>> from pandas.core import nanops
    >>> s = pd.Series([1, 2, 3, np.nan])
    >>> nanops.nanprod(s)
    6.0
    Nr   r   )r   r   prodr   r   )rN   rg   rh   rk   rl   rw   r2   r2   r3   r   k  s     
    r   znp.ndarray | int)rw   rg   rl   rh   r.   c                 C  sn   |d kr| S |d ks t | dds@|r2| r>dS qj| rjdS n*|rP||}n
||}| rjd| |< | S )Nr   F)ry   r   rO   )rw   rg   rl   rh   Zna_maskr2   r2   r3   r     s    
r   zfloat | np.ndarray)r   rl   rg   r9   r.   c                 C  sz   |dkr4|dk	r |j |  }n
t| }||S |dk	rR|j| || }n| | }t|rl||S |j|ddS )a  
    Get the count of non-null values along an axis

    Parameters
    ----------
    values_shape : tuple of int
        shape tuple from values ndarray, used if mask is None
    mask : Optional[ndarray[bool]]
        locations in values that should be considered missing
    axis : Optional[int]
        axis to count along
    dtype : type, optional
        type to use for count

    Returns
    -------
    count : scalar or array
    NFr   )ro   r   rS   r  r7   r   r    r   )r   rl   rg   r9   nr   r2   r2   r3   r     s    


r   znp.ndarray | float | NaTType)rw   rg   rl   r   rk   r.   c           	      C  s  |dkr|dkr| S |dk	rt | tjr|dk	rN|j| || | dk }n8|| | dk }|d| ||d d  }t||}t|rt| rt| r| 	d} nt
| s| j	ddd} tj| |< nd| |< n@| tk	rt|||rt| dd}t
|r|d	} ntj} | S )
zu
    Returns
    -------
    Dtype
        The product of all elements on a given axis. ( NaNs are treated as 1)
    Nr   r   Zc16r   Fr   r9   rG   )r   rS   r   r   r   Zbroadcast_torO   r   Ziscomplexobjr   r   rG   r   check_below_min_country   r7   )	rw   rg   rl   r   rk   Z	null_maskZbelow_countZ	new_shapeZresult_dtyper2   r2   r3   r     s.    




r   )r   rl   rk   r.   c                 C  s:   |dkr6|dkrt | }n|j|  }||k r6dS dS )a  
    Check for the `min_count` keyword. Returns True if below `min_count` (when
    missing value should be returned from the reduction).

    Parameters
    ----------
    shape : tuple
        The shape of the values (`values.shape`).
    mask : ndarray[bool] or None
        Boolean numpy array (typically of same shape as `shape`) or None.
    min_count : int
        Keyword passed through from sum/prod call.

    Returns
    -------
    bool
    r   NTF)rS   r  ro   r   )r   rl   rk   Z	non_nullsr2   r2   r3   r    s    r  c              
   C  sh   t | tjrFtjdd& tt| dk d| W  5 Q R  S Q R X nt| dk r`| jdS | S d S )NrI   rJ   g+=r   )r   rS   r   rT   r   absr9   r7   )argr2   r2   r3   r  +  s    ,r  pearson)methodmin_periodsr   z
int | None)abr  r  r.   c                C  sp   t | t |krtd|dkr$d}t| t|@ }| sL| | } || }t | |k r^tjS t|}|| |S )z
    a, b: ndarrays
    z'Operands to nancorr must have same sizeNr   )rm   r   r'   r   rS   rG   get_corr_func)r  r  r  r  validrF   r2   r2   r3   nancorr4  s    r  z)Callable[[np.ndarray, np.ndarray], float])r  r.   c                   s|   | dkr$ddl m   fdd}|S | dkrHddl m fdd}|S | d	kr\d
d }|S t| rh| S td|  dd S )NZkendallr   
kendalltauc                   s    | |d S Nr   r2   r  r  r  r2   r3   r   W  s    zget_corr_func.<locals>.funcZspearman	spearmanrc                   s    | |d S r  r2   r  r  r2   r3   r   ^  s    r  c                 S  s   t | |d S )Nr   r   )rS   Zcorrcoefr  r2   r2   r3   r   d  s    zUnknown method 'z@', expected one of 'kendall', 'spearman', 'pearson', or callable)Zscipy.statsr  r   callablerU   )r  r   r2   )r  r   r3   r  Q  s     
r  )r  r   )r  r  r  r   r.   c                C  sr   t | t |krtd|d kr$d}t| t|@ }| sL| | } || }t | |k r^tjS tj| ||dd S )Nz&Operands to nancov must have same sizer   r   r!  )rm   r   r'   r   rS   rG   Zcov)r  r  r  r   r  r2   r2   r3   nancovq  s    r#  c                 C  sH  t | tjrt| st| r*| tj} nt| rz| tj} W n^ t	t
fk
r   z| tj} W n4 t
k
r } zt	d|  d|W 5 d }~X Y nX Y nX tt| s| j} nt| sDt| sDt| sDzt| } W n^ t	t
fk
rB   zt| } W n6 t
k
r< } zt	d|  d|W 5 d }~X Y nX Y nX | S )NzCould not convert z to numeric)r   rS   r   r   r   r   r   r   Z
complex128rR   rU   rO   imagrealr   r   r   r   complex)r   r   r2   r2   r3   r     s,    **r   c                   s    fdd}|S )Nc              	     sh   t | }t |}||B }tjdd  | |}W 5 Q R X | rdt|rT|d}t||tj |S )NrI   r   r   )r%   rS   rT   rO   r   r   r   rG   )r   yZxmaskZymaskrl   rw   opr2   r3   rF     s    
zmake_nancomp.<locals>.fr2   )r)  rF   r2   r(  r3   make_nancomp  s    r*  r   )rN   rh   r.   c             	   C  s   t jdt jft jjt j t jft jdt jft jjt jt jfi| \}}| jj	dksVt
|rt| jjt jt jfs|  }t|}|||< ||dd}|||< n|| dd}|S )a  
    Cumulative function with skipna support.

    Parameters
    ----------
    values : np.ndarray or ExtensionArray
    accum_func : {np.cumprod, np.maximum.accumulate, np.cumsum, np.minimum.accumulate}
    skipna : bool

    Returns
    -------
    np.ndarray or ExtensionArray
    g      ?g        r   r   r   )rS   ZcumprodrG   maximum
accumulater   Zcumsumminimumr9   r   r   rC   r7   r   Zbool_r   r%   )rN   Z
accum_funcrh   Zmask_aZmask_bvalsrl   rw   r2   r2   r3   na_accum_func  s(        

r/  )T)NN)NNN)N)r   )t
__future__r   r]   rL   operatortypingr   r   r   r   numpyrS   Zpandas._configr   Zpandas._libsr   r   r	   r
   Zpandas._typingr   r   r   r   r   r   r   r   r   Zpandas.compat._optionalr   Zpandas.util._exceptionsr   Zpandas.core.dtypes.commonr   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   Zpandas.core.dtypes.dtypesr$   Zpandas.core.dtypes.missingr%   r&   r'   Zpandas.core.constructionr(   rz   r0   r1   r4   r5   rc   rr   rt   r   r   r   r   r   r   rq   r   r   r   r~   r   r   r   r   r9   r   r   r   r   r   r   ZnanminZnanmaxr   r   r  r  r   r   r   r   r  r  r  r  r#  r   r*  gtZnangtgeZnangeltZnanltleZnanleeqZnaneqneZnanner/  r2   r2   r2   r3   <module>   s  ,@ 8   /   Y)"%:7". ?P 
/-J4--Xa +
. 0	  





