U
    f/ev                    @  s  d dl mZ d dlmZ d dlZd dl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mZ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 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, d dl-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 d dl7m8Z8m9Z9m:Z: d dl;m<Z<m=Z=m>Z>m?Z? d dl@mAZA d dlBmCZCmDZDmEZE d dlFmG  mHZ d dlImJZJmKZKmLZLmMZMmNZNmOZO d dlPmQZQ d dlRmSZSmTZTmUZU d dlVmWZW d dlXmYZYmZZZm[Z[m\Z\m]Z]m^Z^m_Z_m`Z`maZa d dlbmcZc d dldmeZe d dlfmG  mgZh d dlimG  mj  mkZk d dllmmZmmnZn d dlompZpmqZqmrZrmsZs d dltmG  muZu erld dlvmwZwmxZx eydZzdddddZ{G dd  d eeZ|G d!d" d"e|Z}G d#d$ d$ej|e}Z~G d%d& d&eje|ZG d'd( d(eZG d)d* d*eje}ZG d+d, d,eZG d-d. d.eZG d/d0 d0eZG d1d2 d2e~Zd3d4d5d6ZdZd7d8d9d:Zdd;d<d d=d>d?Zd@d<dAdBdCZdDdEd<dFdGdHdIZd[dJd4dKdLZd\d3d<d3dNdOdPZdQdddRdSd3dTdUdVdWZd3d3dUdXdYZdS )]    )annotations)wrapsN)TYPE_CHECKINGAnyCallableIterableSequencecast)	Timestampalgos	internalslibwriters)BlockPlacement)	ArrayLikeDtypeDtypeObjFShapefinal)cache_readonly)validate_bool_kwarg)astype_array_safecan_hold_elementfind_common_typeinfer_dtype_frommaybe_downcast_numericmaybe_downcast_to_dtypemaybe_upcastsoft_convert_objects)	is_1d_only_ea_dtypeis_1d_only_ea_objis_categorical_dtypeis_dtype_equalis_extension_array_dtypeis_list_like	is_sparseis_string_dtypepandas_dtype)CategoricalDtypeExtensionDtypePandasDtype)ABCDataFrameABCIndexABCPandasArray	ABCSeries)is_inferred_bool_dtype)is_valid_na_for_dtypeisnana_value_for_dtype)extract_bool_arrayputmask_inplaceputmask_smartputmask_without_repeatsetitem_datetimelike_compatvalidate_putmask)quantile_compat)compare_or_regex_searchreplace_regexshould_use_regex)shift)	CategoricalDatetimeArrayExtensionArrayFloatingArrayIntegerArrayIntervalArrayPandasArrayPeriodArrayTimedeltaArray)NDArrayBackedExtensionArray)PandasObject)ensure_wrapped_if_datetimelikeextract_array)check_setitem_lengthsis_empty_indexeris_exact_shape_matchis_scalar_indexer)Float64IndexIndexobjectr   )methreturnc                   s$   t  dd fdd}tt|S )zp
    If we have a multi-column block, split and operate block-wise.  Otherwise
    use the original method.
    list[Block]rT   c                   s>   | j dks| jd dkr( | f||S | j f||S d S )N   r   )ndimshapesplit_and_operate)selfargskwargsrS    @/tmp/pip-unpacked-wheel-tiezk1ph/pandas/core/internals/blocks.pynewfunc   s    zmaybe_split.<locals>.newfunc)r   r	   r   )rS   ra   r_   r^   r`   maybe_split   s    rb   c                   @  s$  e Zd ZU dZded< ded< ded< dZd	Zd	Zd	Zd
Z	d
Z
eedd ZeddddZeeddddZeeddddZeeddddZedd ZeddddZddddd d!Zeed"d# Zed$dd%d&Zejd$d'd(d&Zedd dd)d*Zedd+d d,d-d.Zed/dd0d1Zeddd2d3Zd4d5 Zed dd6d7Zd8d d9d:d;Zed$d d<d=d>Z ed?dd@dAZ!eedBddCdDZ"dEdF Z#dGdH Z$dIddJdKZ%edLddMdNZ&dddLdOdPdQZ'edLddRdSZ(dddLdTdUdVZ)edLddWdXZ*edLddYdZZ+eddLdLd[d\d]Z,eddLdd^d_Z-e.dLdd`daZ/eddd/dcdddeZ0ddddddLdfdgdhZ1ediddjdkdlZ2edmddndodpZ3eddrdsZ4edddtdudvZ5eddddLdwdxdyZ6eddddLdzd{d|Z7edd}d~dddLdddZ8edddddLdddZ9dd Z:dLdddZ;ed dddZ<dd/ddddd/dddddLdddZ=de>j?fdd+d dddZ@ddddLdddZAddddidLdddZBddLdddZCdd ZDedddd dddZEdS )Blockz
    Canonical n-dimensional unit of homogeneous dtype contained in a pandas
    data structure

    Index-ignorant; let the container take care of that
    np.ndarray | ExtensionArrayvaluesintrX   r   __init__r_   FTc                 C  s   | j | jjfS N)_can_consolidatedtypenamer[   r_   r_   r`   _consolidate_key   s    zBlock._consolidate_keyboolrV   c                 C  s   | j }ttj|}|jdk	S z(return a boolean if I am possibly a viewN)re   r	   npndarraybase)r[   re   r_   r_   r`   is_view   s    zBlock.is_viewc                 C  s"   | j }t|tj r|jdkS |jS )z7
        Can we store NA values in this Block?
        )biu)rj   
isinstancerp   kind_can_hold_nar[   rj   r_   r_   r`   ry      s    
zBlock._can_hold_nac                 C  s   t jdtdd t| jtS )NzBlock.is_categorical is deprecated and will be removed in a future version.  Use isinstance(block.values, Categorical) instead.  See https://github.com/pandas-dev/pandas/issues/40226   )
stacklevel)warningswarnDeprecationWarningrw   re   r?   rl   r_   r_   r`   is_categorical   s    zBlock.is_categoricalc                 C  s
   t | jS )z^
        We can be bool if a) we are bool dtype or b) object dtype with bool objects.
        )r0   re   rl   r_   r_   r`   is_bool   s    zBlock.is_boolc                 C  s
   t | jS rh   )external_valuesre   rl   r_   r_   r`   r      s    zBlock.external_valuesrA   c                 C  s
   t | jS )zP
        The array that Series.array returns. Always an ExtensionArray.
        )rE   re   rl   r_   r_   r`   array_values   s    zBlock.array_valuesNDtypeObj | None
np.ndarrayrj   rT   c                 C  s   |t kr| jt S | jS )z
        return an internal format, currently just the ndarray
        this is often overridden to handle to_dense like operations
        )
_dtype_objre   astyperz   r_   r_   r`   
get_values   s    zBlock.get_valuesc                 C  s   t | jddS )NF)compat)r3   rj   rl   r_   r_   r`   
fill_value   s    zBlock.fill_valuer   c                 C  s   | j S rh   	_mgr_locsrl   r_   r_   r`   mgr_locs   s    zBlock.mgr_locs)new_mgr_locsc                 C  s
   || _ d S rh   r   )r[   r   r_   r_   r`   r      s    c                 C  s2   |dkr| j }| jr"t|| jd}t||| jdS )zm
        Create a new block, with type inference propagate any values that are
        not specified
        NrX   	placementrX   )r   is_extensionensure_block_shaperX   	new_blockr[   re   r   r_   r_   r`   
make_block   s
    zBlock.make_blockBlockPlacement | None)r   rT   c                 C  s6   |dkr| j }|jjdkr"t|}t| ||| jdS )z2Wrap given values in a block of same type as self.NmMr   )r   rj   rx   rJ   typerX   r   r_   r_   r`   make_block_same_class  s
    zBlock.make_block_same_classstrc                 C  sj   t | j}| jdkr0| dt|  d| j }n6ddd | jD }| d| jj d| d| j }|S )	NrW   z: z dtype: z x c                 s  s   | ]}t |V  qd S rh   )r   .0sr_   r_   r`   	<genexpr>  s     z!Block.__repr__.<locals>.<genexpr>z, z	, dtype: )	r   __name__rX   lenrj   joinrY   r   indexer)r[   rk   resultrY   r_   r_   r`   __repr__  s    

 zBlock.__repr__c                 C  s
   t | jS rh   )r   re   rl   r_   r_   r`   __len__!  s    zBlock.__len__c                 C  s
   | j | S )zreturn a slice of my valuesre   )r[   slicerr_   r_   r`   _slice%  s    zBlock._slicec                 C  sR   t |tr|d n|}| j| }| |}|j| jjkr@tdt| ||| jS )
        Perform __getitem__-like, return result as block.

        Only supports slices that preserve dimensionality.
        r    Only same dim slicing is allowed)rw   tupler   r   rX   re   
ValueErrorr   )r[   r   Zaxis0_slicerr   
new_valuesr_   r_   r`   getitem_block*  s    

zBlock.getitem_blockslice)r   rT   c                 C  s$   | j d|f }t| || j| jdS )zn
        Perform __getitem__-like specialized to slicing along index.

        Assumes self.ndim == 2
        .r   )re   r   r   rX   )r[   r   r   r_   r_   r`   getitem_block_index;  s    zBlock.getitem_block_index)r   rT   c                 C  s2   |  |}|j| jjkr tdt| ||| jS )r   r   )r   rX   re   r   r   )r[   r   r   r   r_   r_   r`   getitem_block_columnsF  s    
zBlock.getitem_block_columnsr   c                 C  s   | j jS rh   )re   rY   rl   r_   r_   r`   rY   T  s    zBlock.shaper   c                 C  s   | j jS rh   )re   rj   rl   r_   r_   r`   rj   X  s    zBlock.dtypec                 C  s
   | j | S rh   r   )r[   ru   r_   r_   r`   iget]  s    z
Block.igetc                 C  s   || j |< dS )z
        Modify block values in-place with new item value.

        Notes
        -----
        `set` never creates a new array or new Block, whereas `setitem` _may_
        create a new array and always creates a new Block.
        Nr   r[   Zlocsre   r_   r_   r`   set_inplace`  s    	zBlock.set_inplaceNonec                 C  sH   t | j|d| _| j|| _z| j  W n tk
rB   Y nX dS );
        Delete given loc(-s) from block in-place.
        r   N)rp   deletere   r   r   _cacheclearAttributeErrorr[   locr_   r_   r`   r   k  s    zBlock.deleterU   c              	   K  s0   t jdd || jf|}W 5 Q R X | |S )z[
        apply the function to my values; return a block if we are not
        one
        ignore)all)rp   Zerrstatere   _split_op_result)r[   funcr]   r   r_   r_   r`   applyw  s    zBlock.applyignore_failuresrT   c              	   C  s|   | j dkstz|| j}W n& ttfk
rB   |r<g  Y S  Y nX | jj dkr`t|gg}n|dd}| |}|gS )Nr{   rW   )	rX   AssertionErrorre   	TypeErrorNotImplementedErrorrp   arrayreshaper   )r[   r   r   r   
res_valuesnbr_   r_   r`   reduce  s    
zBlock.reducec                 C  s   t |rh|jdkrhg }t| jD ]B\}}t|sB|||d  }n|| }| j||d}|| q |S t|tst	|}| |}|gS )NrW   )re   r   )
r$   rX   	enumerater   r!   r   appendrw   rc   maybe_coerce_values)r[   r   nbsru   r   valsblockr_   r_   r`   r     s    

zBlock._split_op_resultinplacerT   c           	      C  s  t |d}t| j}t| j|\}}|dk	rRtjd|d}d||| jd |k< | jsl|rb| gS | 	 gS | 
|r|r~| n| 	 }t|j|| ||g|S |r|r| gS | 	 gS | jdks| jd dkr| |}|j||dddS | jt| j|||ddS dS )	zs
        fillna on the block with the value. If we fail, then convert to
        ObjectBlock and try again
        r   N)limitFrW   r   T)r   r   downcast)r   r2   re   r9   libalgosZvalidate_limitZcumsumrX   ry   copy_can_hold_elementr5   _maybe_downcastrY   coerce_to_target_dtypefillnarZ   r   )	r[   valuer   r   r   masknoopr   blkr_   r_   r`   r     s4    




    zBlock.fillnac                 C  sX   | j dkstg }t| jD ]6\}}| jt||d  }| |t|}|| q|S )zD
        Split a block into a list of single-column blocks.
        r{   rW   )	rX   r   r   r   re   r   r   r   r   )r[   Z
new_blocksru   Zref_locr   r   r_   r_   r`   _split  s    zBlock._splitc                 O  sL   | j dkr| jd dkstg }|  D ]}||f||}|| q(|S )z
        Split the block and apply func column-by-column.

        Parameters
        ----------
        func : Block method
        *args
        **kwargs

        Returns
        -------
        List[Block]
        r{   r   rW   )rX   rY   r   r   extend)r[   r   r\   r]   
res_blocksr   rbsr_   r_   r`   rZ     s    zBlock.split_and_operate)blocksrT   c                   sV   | j tkr( d k	r|S tdd |D S  d kr@| j jdkr@|S t fdd|D S )Nc                 S  s   g | ]}|j d ddqS )TF)datetimenumericconvert)r   r   r_   r_   r`   
<listcomp>  s     z)Block._maybe_downcast.<locals>.<listcomp>)fr   r   c                   s   g | ]}|  qS r_   r   r   rt   r   r_   r`   r     s     )rj   r   extend_blocksrx   )r[   r   r   r_   r   r`   r     s    
zBlock._maybe_downcastc                 C  s   |dkr| gS | j }| jdkr@|dkr*d}t||}| |gS |dkrN| gS |dksjt|tsjtdn|dkrztd|  S )z:try to downcast each item to the dict of dtypes if presentFrW   Ninferz:downcast must have a dictionary or 'infer' as its argumentz#dtypes as dict is not supported yet)	re   rX   r   r   rw   dictr   r   _downcast_2d)r[   Zdtypesre   nvr_   r_   r`   r     s"    

zBlock.downcastc                 C  s   t | jdd}| |gS )zs
        downcast specialized to 2D case post-validation.

        Refactored to allow use of maybe_split.
        r   rj   )r   re   r   )r[   r   r_   r_   r`   r   2  s    zBlock._downcast_2draiser   errorsc                 C  sl   | j }t||||d}t|}| |}|j| jkrhtd| d| jj d| j d|jj d|j d|S )a  
        Coerce to the new dtype.

        Parameters
        ----------
        dtype : str, dtype convertible
        copy : bool, default False
            copy if indicated
        errors : str, {'raise', 'ignore'}, default 'raise'
            - ``raise`` : allow exceptions to be raised
            - ``ignore`` : suppress exceptions. On error return original object

        Returns
        -------
        Block
        r   zcannot set astype for copy = [z] for dtype (z [z]) to different shape (z]))re   r   r   r   rY   r   rj   rk   )r[   rj   r   r   re   r   Znewbr_   r_   r`   r   <  s    
.zBlock.astyper   r   r   	timedeltarT   c                 C  s   |r|   gS | gS )z
        attempt to coerce any object types to better types return a copy
        of the block (if copy = True) by definition we are not an ObjectBlock
        here!
        r   )r[   r   r   r   r   r_   r_   r`   r   \  s    zBlock.convertr   )elementrT   c                 C  s   t |dd}t| j|S )z#require the same dtype as ourselvesTZextract_numpy)rK   r   re   )r[   r   r_   r_   r`   r   j  s    zBlock._can_hold_elementr   )r   rT   c                 C  s   t |j| jS )z
        Should we set self.values[indexer] = value inplace or do we need to cast?

        Parameters
        ----------
        value : np.ndarray or ExtensionArray

        Returns
        -------
        bool
        )r#   rj   )r[   r   r_   r_   r`   should_storep  s    zBlock.should_storenanc                 K  s"   t | jf||d|}| |S )"convert to our native types format)na_repquoting)to_native_typesre   r   )r[   r  r  r]   r   r_   r_   r`   r    s    zBlock.to_native_types)deepc                 C  s   | j }|r| }| |S )zcopy constructor)re   r   r   )r[   r  re   r_   r_   r`   r     s    z
Block.copy)r   regexrT   c           	      C  s4  t |d}| j}t|trB|r"| n|  }|jj||dd |gS t||}|r`| j|||dS | |s~|rt| gS |  gS t	
||}| s|r| gS |  gS | |r|r| n|  }t|j|| |jddd}|S | jdks| jd dkr| |}|j||d|dS | jt| j||d|d	S d
S )z
        replace the to_replace value with value, possible to create new
        blocks here this is just a call to putmask. regex is not used here.
        It is used in ObjectBlocks.  It is here for API compatibility.
        r   T)r   Fr   r   rW   r   )
to_replacer   r   r  r   r  N)r   re   rw   r?   r   replacer=   _replace_regexr   missingmask_missinganyr5   r   rX   rY   r   rZ   r   )	r[   r	  r   r   r  re   r   r   r   r_   r_   r`   r    sD    





	    zBlock.replace)r   r   rT   c           	      C  sZ   |  |s|r| gS |  gS t|}|r2| jn| j }t|||| | |}|gS )aP  
        Replace elements by the given value.

        Parameters
        ----------
        to_replace : object or pattern
            Scalar to replace or regular expression to match.
        value : object
            Replacement object.
        inplace : bool, default False
            Perform inplace modification.
        convert : bool, default True
            If true, try to coerce any object types to better types.
        mask : array-like of bool, optional
            True indicate corresponding element is ignored.

        Returns
        -------
        List[Block]
        )r   r   recompilere   r<   r   )	r[   r	  r   r   r   r   rxr   r   r_   r_   r`   r    s    


zBlock._replace_regexzIterable[Any]zSequence[Any])src_list	dest_listr   r  rT   c              	     s  j ttr6tt|dkr6||d |S fddt||D }t|sj|r`gS  gS t|d }t	rt
   fdd|D }nfdd|D }dd |D }|rȈn g}t|D ]\}	\}
}|	|k}g }t|D ]\}}t|dkr||	 }n(||	 }t|tr2t|||d  }|j|
|||d}|rv|jrvtd	d |D }|| q|}q|S )
z;
        See BlockManager._replace_list docstring.
        rW   r   c                   s"   g | ]\}}  |r||fqS r_   )r   )r   xyrl   r_   r`   r     s    
 z'Block._replace_list.<locals>.<listcomp>c                   s    g | ]}t |d   dqS )r   )r  r   )r;   r   )r   r  re   r_   r`   r     s   c                   s   g | ]}t  |d  qS )r   )r  r  r   r   r_   r`   r   $  s     c                 S  s   g | ]}t |qS r_   )r4   )r   r  r_   r_   r`   r   )  s     )r	  r   r   r   r  c                 S  s   g | ]}|j d ddqS )FTr  r   r   r_   r_   r`   r   D  s     )re   rw   r?   r   r   uniquer  zipr   r'   r2   r   rn   r   _replace_coerce	is_objectr   r   )r[   r  r  r   r  pairsZsrc_lenmasksrbru   srcdestr   Znew_rbZblk_numr   r   Zmibr   r_   )r   r  r[   re   r`   _replace_list  sP    


zBlock._replace_list)r   r   r  rT   c                 C  sx   |  rr|s>| |}|| kr*|s*| }t|j|| |gS t||}|r`| j|||d|dS | j|||ddS | gS )ai  
        Replace value corresponding to the given boolean array with another
        value.

        Parameters
        ----------
        to_replace : object or pattern
            Scalar to replace or regular expression to match.
        value : object
            Replacement object.
        mask : np.ndarray[bool]
            True indicate corresponding element is ignored.
        inplace : bool, default True
            Perform inplace modification.
        regex : bool, default False
            If true, perform regular expression substitution.

        Returns
        -------
        List[Block]
        F)r   r   r   r
  )r  r   r   r5   re   r=   r  r  )r[   r	  r   r   r   r  r   r_   r_   r`   r  J  s$    

zBlock._replace_coercec           	      C  s  | j dk}t|tjr2|j | j kr2td| j  |dkrF| jrFtj}| j}| |sh| 	|
||S tt|ddrd}|}nd}t|}|r|j}t||| t||}t||rnt|| j r|||< n|rt|jr|||< n|r2|r2| js"t|ttfr"||jj||< nt|||< n<|rB|||< n,|rR|||< nt|t|| |}|||< |rz|j}| |}|S )a  
        Attempt self.values[indexer] = value, possibly creating a new array.

        Parameters
        ----------
        indexer : tuple, list-like, array-like, slice
            The subset of self.values to set
        value : object
            The value being set

        Returns
        -------
        Block

        Notes
        -----
        `indexer` is a direct slice/positional indexer. `value` must
        be a compatible shape.
        r{   zCannot set values with ndim > Nrj   TF)rX   rw   rp   rq   r   
is_numericr  re   r   r   setitemr$   getattrasarrayTrL   rN   rM   rO   r"   rj   r  rC   rB   to_numpynumpy_dtyper8   r   r   )	r[   r   r   	transposere   Zis_ea_valueZ	arr_valueZexact_matchr   r_   r_   r`   r"  ~  sT    








 
 
zBlock.setitemc                 C  sH  |}t | jj|\}}t|tttfr*t| jsBt	|| j
rB| j}| |rbt| jj|| | gS |rl| gS t|\}}|jdkr| || S | jdks| jd dkrt| jj||j}| |gS t|tj}g }	|  }
t|
D ]X\}}|}|r|dd||d f }|dd||d f }|||}|	| q|	S dS )aV  
        putmask the data to the block; it is possible that we may create a
        new dtype of block

        Return the resulting block(s).

        Parameters
        ----------
        mask : np.ndarray[bool], SparseArray[bool], or BooleanArray
        new : a ndarray/object

        Returns
        -------
        List[Block]
        r   rW   r   N)r9   re   r%  rw   r-   r/   r,   r   r  r1   rj   r   r   r7   r   rx   whererX   rY   r6   r   rp   rq   r   r   putmaskr   )r[   r   newZ	orig_maskr   rj   _r   Zis_arrayr   r   ru   r   nZsubmaskr   r_   r_   r`   r*    s6    

zBlock.putmaskc                 C  s,   t |dd\}}t| j|g}| j|ddS )z
        coerce the current block to a dtype compat for other
        we will return a block, possibly object, and not raise

        we can also safely try to coerce to the same dtype
        and will receive the same block
        T)r(   Fr   )r   r   rj   r   )r[   otherrj   r,  Z	new_dtyper_   r_   r`   r      s    
zBlock.coerce_to_target_dtypepadr   forwardzIndex | Nonez
int | Nonez
str | Nonez
Any | None)methodaxisindexr   r   limit_direction
limit_arear   coercer   rT   c              
   K  s   t |d}| js$|r| gS |  gS zt|}W n tk
rJ   d }Y nX |d krf| jjdkrf| gS |rp| jn| j }t	t
j|}tj|f|||||||d|}t|}| |g}| ||
S )Nr   r   )r1  r2  r3  r   r4  r5  r   )r   ry   r   r  Zclean_fill_methodr   rj   rx   re   r	   rp   rq   Zinterpolate_array_2dr   r   r   )r[   r1  r2  r3  r   r   r4  r5  r   r6  r   r]   r   dataZinterp_valuesr   r_   r_   r`   interpolate0  s6    

	zBlock.interpolater2  r   rT   c                 C  s   | j }|tjkr| j}d}nd}tj|||||d}|dkrH|dkrHt|dkrV| j}t|j	| j	sp| 
||S | ||S dS )zQ
        Take values according to indexer and return them as a block.bb

        FT)r2  
allow_fillr   r   N)re   r   
no_defaultr   r   take_ndr   r   r#   rj   r   r   )r[   r   r2  r   r   re   r:  r   r_   r_   r`   r<  b  s$    
    zBlock.take_ndrW   r-  r2  rT   c                 C  s"   t j| j||dd}| j|dgS )z'return block for the diff of the values   )r2  r|   r   )r   diffre   r   )r[   r-  r2  r   r_   r_   r`   r?    s    z
Block.diffperiodsr2  r   rT   c                 C  s*   t | j|\}}t||||}| |gS )z+shift the block by periods, possibly upcast)r   re   r>   r   r[   rA  r2  r   r   r_   r_   r`   r>     s        zBlock.shiftc                 C  s  |j | j kstt|tttfr$t|dks0t| j dk}| j}|}|rN|j}t|| \}}t	|| j
rz| j
tkrz| j}|r| }	np| |s| |}
|
j|||d}| |dS t|| |}||k	r| }	t|	|| nt| ||}	| js| j dkr$|r|	j}	| |	gS | }|j d }||d}|jdd}g }|| fD ]^}| rZttj|	}	|	j| d |d}t || j
}| j|j| j!| d}|"| qZ|S )	a  
        evaluate the block; return result block(s) from the result

        Parameters
        ----------
        other : a ndarray/object
        cond : np.ndarray[bool], SparseArray[bool], or BooleanArray
        errors : str, {'raise', 'ignore'}, default 'raise'
            - ``raise`` : allow exceptions to be raised
            - ``ignore`` : suppress exceptions. On error return original object

        Returns
        -------
        List[Block]
        )r   r   r{   r   r   rW   r   r2  )r   )#rX   r   rw   r-   r/   r,   re   r%  r9   r1   rj   r   r   r   r   r   r)  r   r8   sumrp   r*  expressionsry   r   Zswapaxesr   r  r	   rq   takeZnonzeror   r   r   )r[   r.  condr   r(  re   Z
orig_othericondr   r   r   r   Zaltr2  r   Zresult_blocksr   Ztakenrr   r_   r_   r`   r)    sV    



  

zBlock.wherec                 C  sJ   |j | jj|d\}}|d}|j| }|| }t||ddg}||fS )a  
        Return a list of unstacked blocks of self

        Parameters
        ----------
        unstacker : reshape._Unstacker
        fill_value : int
            Only used in ExtensionBlock._unstack

        Returns
        -------
        blocks : list of Block
            New blocks of unstacked values.
        mask : array-like of bool
            The mask of columns of `blocks` we should keep.
        r   r   r{   r   )get_new_valuesre   r%  r  r   )r[   	unstackerr   new_placementr   r   r   r_   r_   r`   _unstack  s     


zBlock._unstacklinearrP   )qsr2  rT   c                 C  sL   | j dkst|dkstt|s&tt| jt|j|}t|| j	ddS )a\  
        compute the quantiles of the

        Parameters
        ----------
        qs : Float64Index
            List of the quantiles to be computed.
        interpolation : str, default 'linear'
            Type of interpolation.
        axis : int, default 0
            Axis to compute.

        Returns
        -------
        Block
        r{   rW   r   )
rX   r   r%   r:   re   rp   r$  Z_valuesr   r   )r[   rQ  interpolationr2  r   r_   r_   r`   quantile  s
    zBlock.quantile)N)N)N)F)NFN)N)N)Fr   )TTTT)r  N)T)FF)FTN)FF)TF)
r/  r   NFNr0  NNFN)rW   )r   N)r   )rP  r   )Fr   
__module____qualname____doc____annotations__	__slots__r!  r  r   ri   _validate_ndimr   r   rm   propertyrs   ry   r   r   r   r   r   r   r   setterr   r   r   r   r   r   r   r   rY   rj   r   r   r   r   r   r   r   r   rZ   r   r   rb   r   r   r   r   r   r  r   r  r  r   r  r"  r*  r   r8  r   r;  r<  r?  r>   r)  rO  rS  r_   r_   r_   r`   rc      s  
	

 
     *	!    
  A   )  L  3aA          $6&U   rc   c                   @  sV   e Zd ZU dZded< ddddZedddd	ZddddddZdddZ	d
S )EABackedBlockz>
    Mixin for Block subclasses backed by ExtensionArray.
    rA   re   r   rV   c                 C  sD   | j || _ | j|| _z| j  W n tk
r>   Y nX dS )r   N)re   r   r   r   r   r   r   r   r_   r_   r`   r   7  s    zEABackedBlock.deletec                 C  s   | j S rh   r   rl   r_   r_   r`   r   D  s    zEABackedBlock.array_valuesNr   r   r   c                 C  s*   | j }|tkr|t}t|| jS )zS
        return object dtype as boxed values, such as Timestamps/Timedelta
        )re   r   r   rR   rp   r$  r   rY   )r[   rj   re   r_   r_   r`   r   H  s    
zEABackedBlock.get_valuesr/  r   Fc           	      K  sH   | j }|jdkr.|dkr.|jj|||dj}n|j|||d}| |S )Nr{   r   )r   r1  r   )re   rX   r%  r   r   )	r[   r1  r2  r   r   r   r]   re   r   r_   r_   r`   r8  R  s
    zEABackedBlock.interpolate)N)r/  r   FNN)
r   rT  rU  rV  rW  r   r   r   r   r8  r_   r_   r_   r`   r\  0  s   
         r\  c                      s   e Zd ZU dZdZdZdZded< edddd	Z	d
d Z
dd ZddddZeddddZedd Zdd ZddejfddddddZd d! Zd2ddd"d#d$Zd3dddd& fd'd(Zd4ddd)dd*d+d,Zd5ddd.d/Zd0d1 Z  ZS )6ExtensionBlocka  
    Block for holding extension types.

    Notes
    -----
    This holds all 3rd-party extension array types. It's also the immediate
    parent class for our internal extension types' blocks, CategoricalBlock.

    ExtensionArrays are limited to 1-D.
    FTrA   re   r   rV   c                 C  s*   | j dkrt| jfS t| jt| jfS NrW   )rX   r   re   r   rl   r_   r_   r`   rY   p  s    
zExtensionBlock.shapec                 C  s   | j dkrrt|trr|\}}t|s>|dkr>t|  dn*t|trh|td kr\t|| j|g S | j| S |dkrt|  d| jS d S )Nr{   r   z only contains one item)	rX   rw   r   comZis_null_slice
IndexErrorr   r   re   )r[   colr   r_   r_   r`   r   w  s    

zExtensionBlock.igetc                 C  s@   |  dgkst|| _z| j  W n tk
r:   Y nX d S )Nr   )tolistr   re   r   r   r   r   r_   r_   r`   r     s    zExtensionBlock.set_inplacerU   c                 C  sh   t |}| j}t|tjtfr6t|t|kr6|| }|j|jd krR||j	}|||< | j
|dgS )z+
        See Block.putmask.__doc__
        rW   r   )r4   re   rw   rp   rq   rA   r   rX   r   rY   r   )r[   r   r+  r   r_   r_   r`   r*    s     zExtensionBlock.putmaskrn   c                 C  s   dS )z,Extension arrays are never treated as views.Fr_   rl   r_   r_   r`   rs     s    zExtensionBlock.is_viewc                 C  s
   | j jjS rh   )re   rj   Z_is_numericrl   r_   r_   r`   r!    s    zExtensionBlock.is_numericc                 C  sJ   |  |s| t||S t|tr.|d }t||| j || j|< | S )a2  
        Attempt self.values[indexer] = value, possibly creating a new array.

        This differs from Block.setitem by not allowing setitem to change
        the dtype of the Block.

        Parameters
        ----------
        indexer : tuple, list-like, array-like, slice
            The subset of self.values to set
        value : object
            The value being set

        Returns
        -------
        Block

        Notes
        -----
        `indexer` is a direct slice/positional indexer. `value` must
        be a compatible shape.
        r   )r   r   rR   r"  rw   r   rL   re   )r[   r   r   r_   r_   r`   r"    s    


zExtensionBlock.setitemr   Nrf   r   rc   r9  c                 C  sP   |t jkrd}| jj||dd}| jdkr6|dkr6t|dkrD| j}| ||S )zN
        Take values according to indexer and return them as a block.
        NT)r   r:  rW   )r   r;  re   rG  rX   r   r   r   )r[   r   r2  r   r   r   r_   r_   r`   r<    s    

zExtensionBlock.take_ndc                 C  s   t |ts | jdkr |tdf}t |trxt|dkrx|d }t |tsRtd|| j| }t|rn|d }n
td|| j| S )a  
        Return a slice of my values.

        Parameters
        ----------
        slicer : slice, ndarray[int], or a tuple of these
            Valid (non-reducing) indexer for self.values.

        Returns
        -------
        np.ndarray or ExtensionArray
        r{   Nr   z+invalid slicing for a 1-ndim ExtensionArrayrW   )rw   r   rX   r   r   r   r   re   )r[   r   firstZnew_locsr_   r_   r`   r     s"    
 

 zExtensionBlock._slicer   c                 C  s   | j j||d}| j|dgS )Nr   r   r   )re   r   r   )r[   r   r   r   r   re   r_   r_   r`   r     s    zExtensionBlock.fillnarW   r=  c                   s@   |dkr&|dkr&t  jt| jddS |dkr2d}t  ||S )Nr   rD  rW   )superr?  r   re   )r[   r-  r2  	__class__r_   r`   r?    s
    zExtensionBlock.diffr   r@  c                 C  s   | j j||d}| |gS )z
        Shift the block by `periods`.

        Dispatches to underlying ExtensionArray and re-boxes in an
        ExtensionBlock.
        )rA  r   re   r>   r   rB  r_   r_   r`   r>   +  s    zExtensionBlock.shiftr   c              	   C  s8  t |}t|tttfrtt|tjrT|jdkrT|j	d dksDt|d d df }t|tjr|jdkr|j	d dks|t|d d df }t
|rt|r| jj}t| jrd }n| j}| j }| }t
|r|}n|| }z|||< W n: ttfk
r*   t| jjt|| j||d}Y nX | |gS )Nr{   rW   r   r   )r4   rw   r-   r/   r,   r   rp   rq   rX   rY   r   Z	is_scalarr2   rj   Zna_valuer&   re   r   r   r   r   Z_from_sequencer)  r   )r[   r.  rH  r   rj   r   rI  Z	set_otherr_   r_   r`   r)  5  s4    



 zExtensionBlock.wherec           	        sT   j d }t|}|j|dd\}}|d} fddt|j|D }||fS )Nr   rK  r   c              	     s.   g | ]&\}} jj|d  dt|qS )T)r:  r   )r   re   rG  r   )r   indicesZplacer   r[   r_   r`   r   r  s
   z+ExtensionBlock._unstack.<locals>.<listcomp>)rY   rp   ZarangerL  r  r  r%  )	r[   rM  r   rN  Zn_rowsZ	dummy_arrr   r   r   r_   rj  r`   rO  d  s    



zExtensionBlock._unstack)NFN)rW   )r   N)r   )r   rT  rU  rV  ri   rY  r   rW  r   rY   r   r   r*  rZ  rs   r!  r"  r   r;  r<  r   r   r?  r>   r)  rO  __classcell__r_   r_   rf  r`   r]  ^  s8   

+'     
/r]  c                   @  s   e Zd ZU ded< ejjZdS )
NumpyBlockr   re   N)r   rT  rU  rW  libinternalsrl  r   r_   r_   r_   r`   rl  }  s   
rl  c                   @  s   e Zd ZdZdZdS )NumericBlockr_   TN)r   rT  rU  rX  r!  r_   r_   r_   r`   rn    s   rn  c                   @  s   e Zd ZU dZded< ejjZeddddZ	dd	 Z
d
dddZdd
dddZdddd
dddZd dddd
dddZd!dd
dddZdS )"NDArrayBackedExtensionBlockz8
    Block backed by an NDArrayBackedExtensionArray
    rH   re   rn   rV   c                 C  s   | j jjdk	S ro   )re   Z_ndarrayrr   rl   r_   r_   r`   rs     s    z#NDArrayBackedExtensionBlock.is_viewc                 C  s>   |  |s| t||S | j}| jdkr2|j}|||< | S r^  )r   r   rR   r"  re   rX   r%  )r[   r   r   re   r_   r_   r`   r"    s    

z#NDArrayBackedExtensionBlock.setitemrU   c                 C  s>   t |}| |s$| t||S | j}|j|| | gS rh   )r4   r   r   rR   r*  re   r%  )r[   r   r+  arrr_   r_   r`   r*    s    
z#NDArrayBackedExtensionBlock.putmaskr   c              	   C  s^   | j }t|}z|j||j}W n* ttfk
rL   tj| |||d Y S X | |}|gS )NrC  )re   r4   r%  r)  r   r   rc   r   )r[   r.  rH  r   rp  r   r   r_   r_   r`   r)    s    
z!NDArrayBackedExtensionBlock.wherer   rf   r=  c                 C  s$   | j }||j||d }| |gS )a  
        1st discrete difference.

        Parameters
        ----------
        n : int
            Number of periods to diff.
        axis : int, default 0
            Axis to diff upon.

        Returns
        -------
        A list with a new Block.

        Notes
        -----
        The arguments here are mimicking shift so they are called correctly
        by apply.
        rD  )re   r>   r   )r[   r-  r2  re   r   r_   r_   r`   r?    s    z NDArrayBackedExtensionBlock.diffNr   r@  c                 C  s"   | j }|j|||d}| |gS )N)r   r2  rh  )r[   rA  r2  r   re   r   r_   r_   r`   r>     s    z!NDArrayBackedExtensionBlock.shiftFr   c                 C  s^   |  |s,| jjdkr,| t||||S | j}|r:|n| }|j||d}| j|dgS )Nr   rd  r   )	r   rj   rx   r   rR   r   re   r   r   )r[   r   r   r   r   re   r   r_   r_   r`   r     s    z"NDArrayBackedExtensionBlock.fillna)r   )r   )r   N)NFN)r   rT  rU  rV  rW  rm  NDArrayBackedBlockr   rZ  rs   r"  r*  r)  r?  r>   r   r_   r_   r_   r`   ro    s   

     ro  c                   @  s"   e Zd ZU dZdZdZded< dS )DatetimeLikeBlockz*Block for datetime64[ns], timedelta64[ns].r_   FzDatetimeArray | TimedeltaArrayre   N)r   rT  rU  rV  rX  r!  rW  r_   r_   r_   r`   rr    s   
rr  c                   @  s*   e Zd ZU dZded< dZdZdZdZdS )DatetimeTZBlockz0implement a datetime64 block with a tz attributer@   re   r_   TFN)	r   rT  rU  rV  rW  rX  r   rY  ri   r_   r_   r_   r`   rs    s   
rs  c                   @  sF   e Zd ZdZdZeddddddZeddddddd	d
dZdS )ObjectBlockr_   TFrn   rU   r   c                 C  sr   | j dkstz|| j}W n tk
r:   |s2 g  Y S X t|tjsLt|j dksZt|dd}| |gS )z;
        For object-dtype, we operate column-wise.
        r{   rW   r   )	rX   r   re   r   rw   rp   rq   r   r   )r[   r   r   resr_   r_   r`   r      s    
zObjectBlock.reducer   c                 C  s0   t | j ||||d}t|| j}| |gS )z
        attempt to cast any object types to better types return a copy of
        the block (if copy = True) by definition we ARE an ObjectBlock!!!!!
        )r   r   r   r   )r   re   Zravelr   rX   r   )r[   r   r   r   r   r   r_   r_   r`   r     s    zObjectBlock.convertN)F)TTTT)r   rT  rU  rX  r  rb   r   r   r_   r_   r_   r`   rt    s       rt  c                   @  s   e Zd ZdZdS )CategoricalBlockr_   N)r   rT  rU  rX  r_   r_   r_   r`   rv  *  s   rv  r   rV   c                 C  sb   t | dd} t| tjr<t| } t| jjtr<tj	| t
d} t| ttfr^| jdk	r^| d} | S )a:  
    Input validation for values passed to __init__. Ensure that
    any datetime64/timedelta64 dtypes are in nanoseconds.  Ensure
    that we do not have string dtypes.

    Parameters
    ----------
    values : np.ndarray or ExtensionArray

    Returns
    -------
    values : np.ndarray or ExtensionArray
    Tr   r   N)rK   rw   rp   rq   rJ   
issubclassrj   r   r   r   rR   r@   rG   freqZ
_with_freqr   r_   r_   r`   r   3  s    
r   zDtype | Noner   c                 C  s   t tj|rt|n| j}|j}|j}t|r4t}nNt|t	rDt
}n>|tkrRt}n0t|trbt}n |dkrpt}n|dkr~t}nt}|S )z
    Find the appropriate Block subclass to use for the given values and dtype.

    Parameters
    ----------
    values : ndarray-like
    dtype : numpy or pandas dtype

    Returns
    -------
    cls : class, subclass of Block
    )r   r   )r   cru   rv   rt   )r	   rp   rj   r(   r   rx   r&   r]  rw   r)   rv  r
   rs  r*   rr  rn  rt  )re   rj   vtyperx   clsr_   r_   r`   get_block_typeS  s"    

r|  )klassrf   )rX   rT   c                C  sX   t |tst|}t| d |\} }t| || |d krBt| | j}t| } || ||dS )N)rX   r   )rw   r   extract_pandas_array
check_ndimr|  rj   r   )re   r   rX   r}  r,  r_   r_   r`   r   |  s    
r   r   r   c                 C  s   | j |kr$td| j  d| dnvt| js~| j |krPtd| j  d| dt|t| krtdt|  dt| n|dkrt|d	krtd
dS )aV  
    ndim inference and validation.

    Validates that values.ndim and ndim are consistent.
    Validates that len(values) and len(placement) are consistent.

    Parameters
    ----------
    values : array-like
    placement : BlockPlacement
    ndim : int

    Raises
    ------
    ValueError : the number of dimensions do not match
    z0Wrong number of dimensions. values.ndim > ndim [z > ]z1Wrong number of dimensions. values.ndim != ndim [z != zWrong number of items passed z, placement implies r{   rW   zneed to splitN)rX   r   r    rj   r   )re   r   rX   r_   r_   r`   r    s    


r  rd   r   z3tuple[np.ndarray | ExtensionArray, DtypeObj | None])re   rj   rX   rT   c                 C  s@   t | tr(|  } |r(|dkr(t| } t |tr8|j}| |fS )zL
    Ensure that we don't allow PandasArray / PandasDtype in internals.
    rW   )rw   r.   r&  rp   Z
atleast_2dr+   r'  )re   rj   rX   r_   r_   r`   r~    s    


r~  rU   c                 C  sf   |dkrg }t | trB| D ]$}t |tr4|| q|| qn t | tsXtt| ||  |S )z.return a new extended blocks, given the resultN)rw   listr   r   rc   r   r   )r   r   rJ  r_   r_   r`   r     s    


r   rW   )re   rX   rT   c                 C  s.   | j |k r*t| js*td| } | dd} | S )z:
    Reshape if possible to have values.ndim == ndim.
    z+np.ndarray | DatetimeArray | TimedeltaArrayrW   r   )rX   r    rj   r	   r   )re   rX   r_   r_   r`   r     s
    


r   r  .)r  r  float_formatdecimalr   )re   rT   c                K  s  t | } t| ttfr<| jf d|i|}|jtdd}|S t| trjt| }t	
| t}|||< |S | jjdkr|dkr|dkrt| }|s| t} nt	j| dd} || |< | jtdd} | S d	d
lm}	 |	| ||||dd}
|
 }|jtdd}|S t| }t|}| jtkrb|sb|rb| t} | jjt	dj |k rp| d| } nt	j| dd} || |< | jtdd} | S dS )r  r  Fr   r   Nr  rR   r   r   )FloatArrayFormatter)r  r  r  r  Zfixed_widthZU1z<U)rJ   rw   r@   rG   Z_format_native_typesr   rR   rA   r2   rp   r$  rj   rx   r   r   Zpandas.io.formats.formatr  Zget_result_as_arrayr   Zword_lenr   itemsize)re   r  r  r  r  r]   r   r   r   r  	formatterru  r  r_   r_   r`   r    sR    



r  c                 C  s4   t | ttfr| tS t | ttfr,| jS | S dS )a+  
    The array that Series.values returns (public attribute).

    This has some historical constraints, and is overridden in block
    subclasses to return the correct array (e.g. period returns
    object ndarray and datetimetz a datetime64[ns] ndarray instead of
    proper extension array).
    N)rw   rF   rD   r   rR   r@   rG   _datar   r_   r_   r`   r   3  s
    	
r   )N)N)rW   )
__future__r   	functoolsr   r  typingr   r   r   r   r   r	   r}   Znumpyrp   Zpandas._libsr
   r   r   r   rm  r   r   Zpandas._libs.internalsr   Zpandas._typingr   r   r   r   r   r   Zpandas.util._decoratorsr   Zpandas.util._validatorsr   Zpandas.core.dtypes.castr   r   r   r   r   r   r   r   Zpandas.core.dtypes.commonr    r!   r"   r#   r$   r%   r&   r'   r(   Zpandas.core.dtypes.dtypesr)   r*   r+   Zpandas.core.dtypes.genericr,   r-   r.   r/   Zpandas.core.dtypes.inferencer0   Zpandas.core.dtypes.missingr1   r2   r3   Zpandas.core.algorithmscoreZ
algorithmsZpandas.core.array_algos.putmaskr4   r5   r6   r7   r8   r9   Z pandas.core.array_algos.quantiler:   Zpandas.core.array_algos.replacer;   r<   r=   Z"pandas.core.array_algos.transformsr>   Zpandas.core.arraysr?   r@   rA   rB   rC   rD   rE   rF   rG   Zpandas.core.arrays._mixinsrH   Zpandas.core.baserI   Zpandas.core.commoncommonr_  Z#pandas.core.computation.expressionsZcomputationrF  Zpandas.core.constructionrJ   rK   Zpandas.core.indexersrL   rM   rN   rO   Zpandas.core.missingr  ZpandasrP   rQ   rj   r   rb   rc   r\  r]  rl  rn  rq  ro  rr  rs  rt  rv  r   r|  r   r  r~  r   r   r  r   r_   r_   r_   r`   <module>   s     (
, ,
         '.  !a.	 )*H