B
    W0d]                 @  s  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	m
Z d dlmZmZ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! d dl"m#Z#m$Z$ erd dl%Z%eG dd de$Z&ddddddZ'G dd de#Z(dS )    )annotationsN)TYPE_CHECKING)libmissing)	ArrayLikeDtypetype_t)function)is_bool_dtypeis_floatis_float_dtypeis_integer_dtypeis_list_likeis_numeric_dtypepandas_dtype)ExtensionDtyperegister_extension_dtype)isna)ops)BaseMaskedArrayBaseMaskedDtypec               @  s   e Zd ZdZdZeddddZedddd	Zed
dddZe	ddddZ
ddddZeddddZeddddZdddddZdS )BooleanDtypeaf  
    Extension dtype for boolean data.

    .. versionadded:: 1.0.0

    .. warning::

       BooleanDtype is considered experimental. The implementation and
       parts of the API may change without warning.

    Attributes
    ----------
    None

    Methods
    -------
    None

    Examples
    --------
    >>> pd.BooleanDtype()
    BooleanDtype
    booleantype)returnc             C  s   t jS )N)npbool_)self r   L/var/www/html/venv/lib/python3.7/site-packages/pandas/core/arrays/boolean.pyr   K   s    zBooleanDtype.typestrc             C  s   dS )Nbr   )r   r   r   r   kindO   s    zBooleanDtype.kindznp.dtypec             C  s
   t dS )Nbool)r   dtype)r   r   r   r   numpy_dtypeS   s    zBooleanDtype.numpy_dtypeztype_t[BooleanArray]c             C  s   t S )zq
        Return the array type associated with this dtype.

        Returns
        -------
        type
        )BooleanArray)clsr   r   r   construct_array_typeW   s    	z!BooleanDtype.construct_array_typec             C  s   dS )Nr   r   )r   r   r   r   __repr__b   s    zBooleanDtype.__repr__r#   c             C  s   dS )NTr   )r   r   r   r   _is_booleane   s    zBooleanDtype._is_booleanc             C  s   dS )NTr   )r   r   r   r   _is_numerici   s    zBooleanDtype._is_numericz$pyarrow.Array | pyarrow.ChunkedArrayr&   )arrayr   c       
      C  s"  ddl }|j| kr(td|j dt||jr<|g}n|j}g }x|D ]}| }|jj	|jt
|d|d g|jdjdd}|jdkr|jj	|jt
|d|d g|jdjdd}| }ntjt
|td	}t||}	||	 qLW |sttjg tjd	tjg tjd	S t|S dS )
zI
        Construct BooleanArray from pyarrow Array/ChunkedArray.
        r   Nz$Expected array of boolean type, got z instead   )offsetF)Zzero_copy_only)r$   )pyarrowr   r   	TypeError
isinstanceZArraychunksZbuffersr&   Zfrom_bufferslenr.   to_numpyZ
null_countr   zerosr#   appendr,   Z_concat_same_type)
r   r,   r/   r2   resultsZarrZbuflistdatamaskZbool_arrr   r   r   __from_arrow__m   s0    


 zBooleanDtype.__from_arrow__N)__name__
__module____qualname____doc__namepropertyr   r"   r%   classmethodr(   r)   r*   r+   r:   r   r   r   r   r   -   s   r   Fr#   ztuple[np.ndarray, np.ndarray])copyr   c             C  sN  t | trD|dk	rtd| j| j } }|r<|  } | }| |fS d}t | tjrp| jtj	krp|rl|  } nt | tjrt
| jrt| }tjt| td}| |  t|| < t||  | j| |  kstd|} ntj| td}tj|dd}d}|d| krtdt|}tjt| td} ||  t| | < ||krt| |  t||  tkstd|dkr|dkrtjt| td}np|dkr|}n`t |tjr|jtj	kr|dk	r||B }n|r| }n tj|td}|dk	r||B }| jd	kr2td
|jd	krFtd| |fS )a  
    Coerce the input values array to numpy arrays with a mask.

    Parameters
    ----------
    values : 1D list-like
    mask : bool 1D array, optional
    copy : bool, default False
        if True, copy the input

    Returns
    -------
    tuple of (values, mask)
    Nz'cannot pass mask for BooleanArray input)r$   zNeed to pass bool-like valuesT)skipna)Zfloatingintegerzmixed-integer-float)r   emptyr-   zvalues must be a 1D list-likezmask must be a 1D list-like)r1   r&   
ValueError_data_maskrB   r   ndarrayr$   r   r   r   r5   r3   r#   astypeallr0   asarrayobjectr   Zinfer_dtypefloatr,   ndim)valuesr9   rB   Zmask_valuesZvalues_boolZvalues_objectZinferred_dtypeZinteger_liker   r   r   coerce_to_array   sd    






rQ   c            	      s`  e Zd ZdZdZdddddhZdd	d
ddhZdBdddd fddZeddddZ	e
dddddd dddZe
ddddddddddd dd d!ZejejeejfZd"d#d$d%d&Zd'dd(d)ZdCdd+d, fd-d.Zddd/d0Zd*d1dd1d2d3Zd*d1dd1d4d5Zd6d7 Zd8d9 Zd:d; Zd*d1d#dd< fd=d>Zd#d?d@dAZ  ZS )Dr&   aZ  
    Array of boolean (True/False) data with missing values.

    This is a pandas Extension array for boolean data, under the hood
    represented by 2 numpy arrays: a boolean array with the data and
    a boolean array with the mask (True indicating missing).

    BooleanArray implements Kleene logic (sometimes called three-value
    logic) for logical operations. See :ref:`boolean.kleene` for more.

    To construct an BooleanArray from generic array-like input, use
    :func:`pandas.array` specifying ``dtype="boolean"`` (see examples
    below).

    .. versionadded:: 1.0.0

    .. warning::

       BooleanArray is considered experimental. The implementation and
       parts of the API may change without warning.

    Parameters
    ----------
    values : numpy.ndarray
        A 1-d boolean-dtype array with the data.
    mask : numpy.ndarray
        A 1-d boolean-dtype array indicating missing values (True
        indicates missing).
    copy : bool, default False
        Whether to copy the `values` and `mask` arrays.

    Attributes
    ----------
    None

    Methods
    -------
    None

    Returns
    -------
    BooleanArray

    Examples
    --------
    Create an BooleanArray with :func:`pandas.array`:

    >>> pd.array([True, False, None], dtype="boolean")
    <BooleanArray>
    [True, False, <NA>]
    Length: 3, dtype: boolean
    FTrueTRUEtrue1z1.0FalseFALSEfalse0z0.0z
np.ndarrayr#   )rP   r9   rB   c               s>   t |tjr|jtjks tdt | _t j	|||d d S )NzIvalues should be boolean numpy array. Use the 'pd.array' function instead)rB   )
r1   r   rI   r$   r   r0   r   _dtypesuper__init__)r   rP   r9   rB   )	__class__r   r   r\   )  s
    zBooleanArray.__init__r   )r   c             C  s   | j S )N)rZ   )r   r   r   r   r$   2  s    zBooleanArray.dtypeN)r$   rB   zDtype | None)r$   rB   r   c            C  s*   |r|dkst t||d\}}t||S )Nr   )rB   )AssertionErrorrQ   r&   )r'   scalarsr$   rB   rP   r9   r   r   r   _from_sequence6  s    zBooleanArray._from_sequence)r$   rB   true_valuesfalse_valuesz	list[str]zlist[str] | None)stringsr$   rB   ra   rb   r   c              sP   | j |pg | j|pg   fddfdd|D }| j|||dS )Nc               s6   t | r| S | krdS |  kr$dS t|  dd S )NTFz cannot be cast to bool)r   rF   )s)false_values_uniontrue_values_unionr   r   
map_stringL  s    z:BooleanArray._from_sequence_of_strings.<locals>.map_stringc               s   g | ]} |qS r   r   ).0x)rg   r   r   
<listcomp>V  s    z:BooleanArray._from_sequence_of_strings.<locals>.<listcomp>)r$   rB   )_TRUE_VALUESunion_FALSE_VALUESr`   )r'   rc   r$   rB   ra   rb   r_   r   )re   rg   rf   r   _from_sequence_of_strings?  s
    

z&BooleanArray._from_sequence_of_stringsznp.ufuncr    )ufuncmethodc       	        s   |dkrt d|dd}x&|| D ]}t|| jtf s&tS q&W tj| ||f||}|tk	rf|S tj	t
| td g }x8|D ]0}t|tr |jO  ||j q|| qW  fddt||||}t|trtfdd	|D  n|S d S )
Nreducez%The 'reduce' method is not supported.outr   )r$   c               s*   t | jr  }t| |S tj|  < | S )N)r
   r$   rB   r&   r   nan)ri   m)r9   r   r   reconstructw  s
    


z1BooleanArray.__array_ufunc__.<locals>.reconstructc             3  s   | ]} |V  qd S )Nr   )rh   ri   )ru   r   r   	<genexpr>  s    z/BooleanArray.__array_ufunc__.<locals>.<genexpr>)NotImplementedErrorgetr1   _HANDLED_TYPESr&   NotImplementedr   Z!maybe_dispatch_ufunc_to_dunder_opr   r5   r3   r#   rH   r6   rG   getattrtuple)	r   ro   rp   inputskwargsrr   ri   resultZinputs2r   )r9   ru   r   __array_ufunc__[  s,    



zBooleanArray.__array_ufunc__ztuple[np.ndarray, np.ndarray]c             C  s   t |S )N)rQ   )r   valuer   r   r   _coerce_to_array  s    zBooleanArray._coerce_to_arrayTr   )rB   r   c               s   t |}t|tr t ||S t|rH| jr8tdn| jj||dS t	|r^| jr^td| j
}t|rrtj}| j||ddS )a  
        Cast to a NumPy array or ExtensionArray with 'dtype'.

        Parameters
        ----------
        dtype : str or dtype
            Typecode or data-type to which the array is cast.
        copy : bool, default True
            Whether to copy the data, even if not necessary. If False,
            a copy is made only if the old dtype does not match the
            new dtype.

        Returns
        -------
        ndarray or ExtensionArray
            NumPy ndarray, BooleanArray or IntegerArray with 'dtype' for its dtype.

        Raises
        ------
        TypeError
            if incompatible type with an BooleanDtype, equivalent of same_kind
            casting
        z cannot convert float NaN to bool)rB   zcannot convert NA to integerF)r$   na_valuerB   )r   r1   r   r[   rJ   r
   Z_hasnarF   rG   r   Z	_na_valuer   r   rs   r4   )r   r$   rB   r   )r]   r   r   rJ     s    

zBooleanArray.astypec             C  s   | j  }d|| j< |S )a=  
        Return values for sorting.

        Returns
        -------
        ndarray
            The transformed values should maintain the ordering between values
            within the array.

        See Also
        --------
        ExtensionArray.argsort : Return the indices that would sort this array.
        )rG   rB   rH   )r   r8   r   r   r   _values_for_argsort  s    

z BooleanArray._values_for_argsort)rC   c            K  sl   | dd td| | j }t|| jd | }|rB|S |s\t	| dks\| j s`|S | j
jS dS )a8  
        Return whether any element is True.

        Returns False unless there is at least one element that is True.
        By default, NAs are skipped. If ``skipna=False`` is specified and
        missing values are present, similar :ref:`Kleene logic <boolean.kleene>`
        is used as for logical operations.

        Parameters
        ----------
        skipna : bool, default True
            Exclude NA values. If the entire array is NA and `skipna` is
            True, then the result will be False, as for an empty array.
            If `skipna` is False, the result will still be True if there is
            at least one element that is True, otherwise NA will be returned
            if there are NA's present.
        **kwargs : any, default None
            Additional keywords have no effect but might be accepted for
            compatibility with NumPy.

        Returns
        -------
        bool or :attr:`pandas.NA`

        See Also
        --------
        numpy.any : Numpy version of this method.
        BooleanArray.all : Return whether all elements are True.

        Examples
        --------
        The result indicates whether any element is True (and by default
        skips NAs):

        >>> pd.array([True, False, True]).any()
        True
        >>> pd.array([True, False, pd.NA]).any()
        True
        >>> pd.array([False, False, pd.NA]).any()
        False
        >>> pd.array([], dtype="boolean").any()
        False
        >>> pd.array([pd.NA], dtype="boolean").any()
        False

        With ``skipna=False``, the result can be NA if this is logically
        required (whether ``pd.NA`` is True or False influences the result):

        >>> pd.array([True, False, pd.NA]).any(skipna=False)
        True
        >>> pd.array([False, False, pd.NA]).any(skipna=False)
        <NA>
        axisNr   Fr   )popnvZvalidate_anyrG   rB   r   putmaskrH   anyr3   r$   r   )r   rC   r~   rP   r   r   r   r   r     s    6
zBooleanArray.anyc            K  sl   | dd td| | j }t|| jd | }|rB|S |r\t	| dks\| j
 s`|S | jjS dS )a  
        Return whether all elements are True.

        Returns True unless there is at least one element that is False.
        By default, NAs are skipped. If ``skipna=False`` is specified and
        missing values are present, similar :ref:`Kleene logic <boolean.kleene>`
        is used as for logical operations.

        Parameters
        ----------
        skipna : bool, default True
            Exclude NA values. If the entire array is NA and `skipna` is
            True, then the result will be True, as for an empty array.
            If `skipna` is False, the result will still be False if there is
            at least one element that is False, otherwise NA will be returned
            if there are NA's present.
        **kwargs : any, default None
            Additional keywords have no effect but might be accepted for
            compatibility with NumPy.

        Returns
        -------
        bool or :attr:`pandas.NA`

        See Also
        --------
        numpy.all : Numpy version of this method.
        BooleanArray.any : Return whether any element is True.

        Examples
        --------
        The result indicates whether any element is True (and by default
        skips NAs):

        >>> pd.array([True, True, pd.NA]).all()
        True
        >>> pd.array([True, False, pd.NA]).all()
        False
        >>> pd.array([], dtype="boolean").all()
        True
        >>> pd.array([pd.NA], dtype="boolean").all()
        True

        With ``skipna=False``, the result can be NA if this is logically
        required (whether ``pd.NA`` is True or False influences the result):

        >>> pd.array([True, True, pd.NA]).all(skipna=False)
        <NA>
        >>> pd.array([True, False, pd.NA]).all(skipna=False)
        False
        r   Nr   Tr   )r   r   Zvalidate_allrG   rB   r   r   rH   rK   r3   r   r$   r   )r   rC   r~   rP   r   r   r   r   rK     s    4
zBooleanArray.allc             C  sJ  |j dkstt|t}t|}d }|r:|j|j }}nNt|rtt	j
|dd}|jdkrbtdt|dd\}}nt|t	jr| }|r|tjk	rt|stdt|j  d	|st| t|krtd
|j dkrt| j|| j|\}}nJ|j dkrt| j|| j|\}}n$|j dkr@t| j|| j|\}}t||S )N>   or_rxorxorrand_and_ror_r#   )r$   r-   z(can only perform ops with 1-d structuresF)rB   z+'other' should be pandas.NA or a bool. Got z	 instead.zLengths must match to compare>   r   r   >   r   r   >   r   r   )r;   r^   r1   r&   r   Z	is_scalarrG   rH   r   r   rL   rO   rw   rQ   r   item
libmissingNAZis_boolr0   r   r3   rF   r   Z	kleene_orZ
kleene_andZ
kleene_xor)r   otheropZother_is_booleanarrayZother_is_scalarr9   r   r   r   r   _logical_methodT  s2    



zBooleanArray._logical_methodc          
   C  s  ddl m}m} t|||fr"tS d }t|tr@|j|j }}n<t|r|t	
|}|jdkrdtdt| t|kr|td|tjkrt	| j}t	| j}ndt 8 tddt t	jdd || j|}W d Q R X W d Q R X |d kr| j }n
| j|B }t||d	d
S )Nr   )FloatingArrayIntegerArrayr-   z(can only perform ops with 1-d structureszLengths must match to compareignoreZelementwise)rK   F)rB   )Zpandas.arraysr   r   r1   rz   r&   rG   rH   r   r   rL   rO   rw   r3   rF   r   r   Z
zeros_likeZ	ones_likewarningscatch_warningsfilterwarningsFutureWarningerrstaterB   )r   r   r   r   r   r9   r   r   r   r   _cmp_methody  s.    




 
zBooleanArray._cmp_methodc       	   	   C  s@  d }|j }t|tr$|j|j }}n<t|r`t|}|jdkrHt	dt
| t
|kr`td|d kr| j}|tjkr|dO }n
| j|B }|tjkr|dkrd}nd}tjt
| j|d}n@|d	krt|tjrt|}tjd
d || j|}W d Q R X |dkr0|\}}| |||d| |||dfS | ||||S )Nr-   z(can only perform ops with 1-d structureszLengths must matchT>   pow	rfloordivrpowfloordivrmodmodZint8r#   )r$   >   r   r   r   )rK   divmodr   r   )r;   r1   r&   rG   rH   r   r   rL   rO   rw   r3   rF   r   r   r5   r   r#   r   _maybe_mask_result)	r   r   r   r9   op_namer$   r   divr   r   r   r   _arith_method  s:    







zBooleanArray._arith_method)r?   rC   c              s8   |dkr t | |f d|i|S t j|fd|i|S )N>   r   rK   rC   )r{   r[   _reduce)r   r?   rC   r~   )r]   r   r   r     s    zBooleanArray._reduce)r   c             C  s|   t |st|s|dkr2ddlm} |||ddS t|rHt||ddS t|rjddlm} |||ddS tj	||< |S dS )z
        Parameters
        ----------
        result : array-like
        mask : array-like bool
        other : scalar or array-like
        op_name : str
        )Zrtruedivtruedivr   )r   F)rB   )r   N)
r   r   Zpandas.core.arraysr   r
   r&   r   r   r   rs   )r   r   r9   r   r   r   r   r   r   r   r     s    
zBooleanArray._maybe_mask_result)F)T) r;   r<   r=   r>   Z_internal_fill_valuerk   rm   r\   r@   r$   rA   r`   rn   r   rI   numbersNumberr#   r   ry   r   r   rJ   r   r   rK   r   r   r   r   r   __classcell__r   r   )r]   r   r&      s2   4	 -0DC%*1r&   )NF))
__future__r   r   typingr   r   numpyr   Zpandas._libsr   r   r   Zpandas._typingr   r   r   Zpandas.compat.numpyr	   r   Zpandas.core.dtypes.commonr
   r   r   r   r   r   r   Zpandas.core.dtypes.dtypesr   r   Zpandas.core.dtypes.missingr   Zpandas.corer   Zpandas.core.arrays.maskedr   r   r/   r   rQ   r&   r   r   r   r   <module>   s$   $	jV