U
    `»{j'Ÿ  ã                   @  s  U d Z ddlmZ ddlZddl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ZddlZddlm  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" dd	l#m$Z$m%Z% dd
l&m'Z' ddl(m)Z)m*Z*m+Z+m,Z,m-Z- ddl.m/Z/m0Z0m1Z1 ddl2m3Z3m4Z4 ddl5m6Z6m7Z7m8Z8 ddl9m:Z: ddl;m<Z<m=Z=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZDmEZEmFZF e�r–ddlmGZGmHZH ddlImJZJmKZK i ZLdeMd< dddddœZNeddd�ZOG dd„ de:ƒZPG dd „ d ƒZQG d!d"„ d"ee ƒZRG d#d„ de@ƒZSdS )$z.
Base and utility classes for pandas objects.
é    )ÚannotationsN)	ÚTYPE_CHECKINGÚAnyÚGenericÚHashableÚLiteralÚTypeVarÚcastÚfinalÚoverload)Ú	ArrayLikeÚDtypeObjÚ
IndexLabelÚNDFrameTÚShapeÚnpt)ÚPYPY)Úfunction©ÚAbstractMethodError)Úcache_readonlyÚdoc)Úfind_stack_level)Úis_categorical_dtypeÚis_dict_likeÚis_extension_array_dtypeÚis_object_dtypeÚ	is_scalar)ÚABCDataFrameÚABCIndexÚ	ABCSeries)ÚisnaÚremove_na_arraylike)Ú
algorithmsÚnanopsÚops)ÚDirNamesMixin)Ú
duplicatedÚunique1dÚvalue_counts)ÚOpsMixin)ÚExtensionArray)Ú!create_series_with_explicit_dtypeÚensure_wrapped_if_datetimelikeÚextract_array)ÚNumpySorterÚNumpyValueArrayLike)ÚCategoricalÚSerieszdict[str, str]Ú_shared_docsÚIndexOpsMixinÚ )ÚklassZinplaceÚuniquer'   Ú_T)Úboundc                      s\   e Zd ZU dZded< edd„ ƒZddœdd	„Zddddœdd„Zddœ‡ fdd„Z	‡  Z
S )ÚPandasObjectz/
    Baseclass for various pandas objects.
    zdict[str, Any]Ú_cachec                 C  s   t | ƒS )zJ
        Class constructor (for this class it's just `__class__`.
        )Útype©Úself© r?   úO/var/www/html/bwave/python/venv/lib/python3.8/site-packages/pandas/core/base.pyÚ_constructorn   s    zPandasObject._constructorÚstr©Úreturnc                 C  s
   t  | ¡S )zI
        Return a string representation for a particular object.
        )ÚobjectÚ__repr__r=   r?   r?   r@   rF   u   s    zPandasObject.__repr__Nz
str | NoneÚNone©ÚkeyrD   c                 C  s4   t | dƒsdS |dkr"| j ¡  n| j |d¡ dS )zV
        Reset cached properties. If ``key`` is passed, only clears that key.
        r;   N)Úhasattrr;   ÚclearÚpop)r>   rI   r?   r?   r@   Ú_reset_cache|   s
    
zPandasObject._reset_cacheÚintc                   s<   t | ddƒ}|r2|dd�}tt|ƒr(|n| ¡ ƒS tƒ  ¡ S )zx
        Generates the total memory usage for an object that returns
        either a value or Series of values
        Úmemory_usageNT©Údeep)ÚgetattrrN   r   ÚsumÚsuperÚ
__sizeof__)r>   rO   Zmem©Ú	__class__r?   r@   rU   ‡   s
    
zPandasObject.__sizeof__)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__ÚpropertyrA   rF   rM   rU   Ú__classcell__r?   r?   rV   r@   r:   f   s   

r:   c                   @  s(   e Zd ZdZdd„ Zdddœdd„Zd	S )
ÚNoNewAttributesMixina„  
    Mixin which prevents adding new attributes.

    Prevents additional attributes via xxx.attribute = "something" after a
    call to `self.__freeze()`. Mainly used to prevent the user from using
    wrong attributes on an accessor (`Series.cat/.str/.dt`).

    If you really want to add a new attribute at a later time, you need to use
    `object.__setattr__(self, key, value)`.
    c                 C  s   t  | dd¡ dS )z9
        Prevents setting additional attributes.
        Ú__frozenTN)rE   Ú__setattr__r=   r?   r?   r@   Ú_freeze¡   s    zNoNewAttributesMixin._freezerB   rG   rH   c                 C  sT   t | ddƒrB|dksB|t| ƒjksBt | |d ƒd k	sBtd|› d�ƒ‚t | ||¡ d S )Nr`   Fr;   z"You cannot add any new attribute 'ú')rR   r<   Ú__dict__ÚAttributeErrorrE   ra   )r>   rI   Úvaluer?   r?   r@   ra   ¨   s    ÿþýz NoNewAttributesMixin.__setattr__N)rX   rY   rZ   r[   rb   ra   r?   r?   r?   r@   r_   •   s   r_   c                   @  s¤   e Zd ZU dZded< dZded< ded< d	d
gZeeƒZe	e
dd„ ƒƒZedd„ ƒZe	eddœdd„ƒƒZe	edd„ ƒƒZdd„ Zdddœdd„Zdd„ ZeZdS )ÚSelectionMixinz‰
    mixin implementing the selection & aggregation interface on a group-like
    object sub-classes need to define: obj, exclusions
    r   ÚobjNzIndexLabel | NoneÚ
_selectionzfrozenset[Hashable]Ú
exclusionsr;   Ú__setstate__c                 C  s&   t | jtttttjfƒs | jgS | jS ©N)Ú
isinstanceri   ÚlistÚtupler    r   ÚnpÚndarrayr=   r?   r?   r@   Ú_selection_listÃ   s     ÿzSelectionMixin._selection_listc                 C  s,   | j d kst| jtƒr| jS | j| j  S d S rl   )ri   rm   rh   r    r=   r?   r?   r@   Ú_selected_objÌ   s    zSelectionMixin._selected_objrN   rC   c                 C  s   | j jS rl   )rs   Úndimr=   r?   r?   r@   rt   Ó   s    zSelectionMixin.ndimc                 C  sN   | j d k	r"t| jtƒr"| j| j S t| jƒdkrD| jj| jddd�S | jS d S )Nr   é   T)ÚaxisZ
only_slice)ri   rm   rh   r   rr   Úlenrj   Z
_drop_axisr=   r?   r?   r@   Ú_obj_with_exclusionsØ   s
    z#SelectionMixin._obj_with_exclusionsc                 C  s  | j d k	rtd| j › d�ƒ‚t|tttttjfƒr’t	| j
j |¡ƒt	t|ƒƒkr€tt|ƒ | j
j¡ƒ}tdt|ƒdd… › �ƒ‚| jt|ƒdd�S t| dd	ƒsÆ|| j
jkr¸td
|› �ƒ‚| j|dd�S || j
krÞtd
|› �ƒ‚| j
| }|j}| j|||d�S d S )Nz
Column(s) z already selectedzColumns not found: ru   éÿÿÿÿé   ©rt   Zas_indexFzColumn not found: )rt   Úsubset)ri   Ú
IndexErrorrm   rn   ro   r    r   rp   rq   rw   rh   ÚcolumnsÚintersectionÚsetÚ
differenceÚKeyErrorrB   Ú_gotitemrR   rt   )r>   rI   Úbad_keysr|   rt   r?   r?   r@   Ú__getitem__ç   s     


zSelectionMixin.__getitem__r{   c                 C  s   t | ƒ‚dS )a  
        sub-classes to define
        return a sliced object

        Parameters
        ----------
        key : str / list of selections
        ndim : {1, 2}
            requested ndim of result
        subset : object, default None
            subset to act on
        Nr   )r>   rI   rt   r|   r?   r?   r@   rƒ   ý   s    zSelectionMixin._gotitemc                 O  s   t | ƒ‚d S rl   r   )r>   ÚfuncÚargsÚkwargsr?   r?   r@   Ú	aggregate  s    zSelectionMixin.aggregate)N)rX   rY   rZ   r[   r\   ri   Z_internal_namesr€   Z_internal_names_setr
   r]   rr   r   rs   rt   rx   r…   rƒ   r‰   Zaggr?   r?   r?   r@   rg   ·   s*   

rg   c                   @  s  e Zd ZU dZdZedgƒZded< eddœdd	„ƒZ	ed
dœdd„ƒZ
dddœdd„Zeedd�Zeddœdd„ƒZddœdd„Zeddœdd„ƒZdd„ Zeddœdd„ƒZeddœd d!„ƒZed"dœd#d$„ƒZd%d&ejfd'd(d)d*d+œd,d-„Zed(dœd.d/„ƒZd‹d(d1œd2d3„Zed4d5d6d7�dŒd(dd8œd9d:„ƒZd�d(d1œd;d<„Zeed5d4d=d7�dŽddœd>d?„ƒZd@dA„ ZeZdBdC„ Ze d(dœdDdE„ƒZ!dFdœdGdH„Z"dId0d%d%dJœdKdLœdMdN„Z#e$d�dOdP„ƒZ%d�d(d(d(d(dQdRœdSdT„Z&dUdV„ Z'd‘d(ddWœdXdY„Z(ed(dœdZd[„ƒZ)ed(dœd\d]„ƒZ*ed(dœd^d_„ƒZ+ed(dœd`da„ƒZ,d’d(ddbœdcdd„Z-ee.j/dededee0 1df¡dg�d&ejejfd(dhdidjœdkdl„ƒZ/dme2dn< e3d“dpdqdrdsdtœdudv„ƒZ4e3d”dwdqdrdxdtœdydv„ƒZ4ee2dn dzd{�d•d}dqdrd~dtœddv„ƒZ4d–d�d‚„Z5e$d—dƒdFd„œd…d†„ƒZ6d‡dˆ„ Z7d‰dŠ„ Z8d%S )˜r4   zS
    Common ops mixin to support a unified interface / docs for Series / Index
    iè  Útolistzfrozenset[str]Ú_hidden_attrsr   rC   c                 C  s   t | ƒ‚d S rl   r   r=   r?   r?   r@   Údtype  s    zIndexOpsMixin.dtypezExtensionArray | np.ndarrayc                 C  s   t | ƒ‚d S rl   r   r=   r?   r?   r@   Ú_values"  s    zIndexOpsMixin._valuesr8   )r>   rD   c                 O  s   t  ||¡ | S )zw
        Return the transpose, which is by definition self.

        Returns
        -------
        %(klass)s
        )ÚnvZvalidate_transpose)r>   r‡   rˆ   r?   r?   r@   Ú	transpose'  s    zIndexOpsMixin.transposezD
        Return the transpose, which is by definition self.
        )r   r   c                 C  s   | j jS )zE
        Return a tuple of the shape of the underlying data.
        )r�   Úshaper=   r?   r?   r@   r�   9  s    zIndexOpsMixin.shaperN   c                 C  s   t | ƒ‚d S rl   r   r=   r?   r?   r@   Ú__len__@  s    zIndexOpsMixin.__len__z
Literal[1]c                 C  s   dS )zO
        Number of dimensions of the underlying data, by definition 1.
        ru   r?   r=   r?   r?   r@   rt   D  s    zIndexOpsMixin.ndimc                 C  s$   t | ƒdkrtt| ƒƒS tdƒ‚dS )a  
        Return the first element of the underlying data as a Python scalar.

        Returns
        -------
        scalar
            The first element of %(klass)s.

        Raises
        ------
        ValueError
            If the data is not length-1.
        ru   z6can only convert an array of size 1 to a Python scalarN)rw   ÚnextÚiterÚ
ValueErrorr=   r?   r?   r@   ÚitemK  s    zIndexOpsMixin.itemc                 C  s   | j jS )zD
        Return the number of bytes in the underlying data.
        )r�   Únbytesr=   r?   r?   r@   r–   ]  s    zIndexOpsMixin.nbytesc                 C  s
   t | jƒS )zG
        Return the number of elements in the underlying data.
        )rw   r�   r=   r?   r?   r@   Úsized  s    zIndexOpsMixin.sizer+   c                 C  s   t | ƒ‚dS )aM  
        The ExtensionArray of the data backing this Series or Index.

        Returns
        -------
        ExtensionArray
            An ExtensionArray of the values stored within. For extension
            types, this is the actual array. For NumPy native types, this
            is a thin (no copy) wrapper around :class:`numpy.ndarray`.

            ``.array`` differs ``.values`` which may require converting the
            data to a different form.

        See Also
        --------
        Index.to_numpy : Similar method that always returns a NumPy array.
        Series.to_numpy : Similar method that always returns a NumPy array.

        Notes
        -----
        This table lays out the different array types for each extension
        dtype within pandas.

        ================== =============================
        dtype              array type
        ================== =============================
        category           Categorical
        period             PeriodArray
        interval           IntervalArray
        IntegerNA          IntegerArray
        string             StringArray
        boolean            BooleanArray
        datetime64[ns, tz] DatetimeArray
        ================== =============================

        For any 3rd-party extension types, the array type will be an
        ExtensionArray.

        For all remaining dtypes ``.array`` will be a
        :class:`arrays.NumpyExtensionArray` wrapping the actual ndarray
        stored within. If you absolutely need a NumPy array (possibly with
        copying / coercing data), then use :meth:`Series.to_numpy` instead.

        Examples
        --------
        For regular NumPy types like int, and float, a PandasArray
        is returned.

        >>> pd.Series([1, 2, 3]).array
        <PandasArray>
        [1, 2, 3]
        Length: 3, dtype: int64

        For extension types, like Categorical, the actual ExtensionArray
        is returned

        >>> ser = pd.Series(pd.Categorical(['a', 'b', 'a']))
        >>> ser.array
        ['a', 'b', 'a']
        Categories (2, object): ['a', 'b']
        Nr   r=   r?   r?   r@   Úarrayk  s    ?zIndexOpsMixin.arrayNFznpt.DTypeLike | NoneÚboolrE   z
np.ndarray)rŒ   ÚcopyÚna_valuerD   c                 K  sŽ   t | jƒr$| jj|f||dœ|—ŽS |rHt| ¡ ƒd }td|› d�ƒ‚tj| j	|d�}|sf|t
jk	rŠ| ¡ }|t
jk	rŠ||t |  ¡ ¡< |S )aö  
        A NumPy ndarray representing the values in this Series or Index.

        Parameters
        ----------
        dtype : str or numpy.dtype, optional
            The dtype to pass to :meth:`numpy.asarray`.
        copy : bool, default False
            Whether to ensure that the returned value is not a view on
            another array. Note that ``copy=False`` does not *ensure* that
            ``to_numpy()`` is no-copy. Rather, ``copy=True`` ensure that
            a copy is made, even if not strictly necessary.
        na_value : Any, optional
            The value to use for missing values. The default value depends
            on `dtype` and the type of the array.

            .. versionadded:: 1.0.0

        **kwargs
            Additional keywords passed through to the ``to_numpy`` method
            of the underlying array (for extension arrays).

            .. versionadded:: 1.0.0

        Returns
        -------
        numpy.ndarray

        See Also
        --------
        Series.array : Get the actual data stored within.
        Index.array : Get the actual data stored within.
        DataFrame.to_numpy : Similar method for DataFrame.

        Notes
        -----
        The returned array will be the same up to equality (values equal
        in `self` will be equal in the returned array; likewise for values
        that are not equal). When `self` contains an ExtensionArray, the
        dtype may be different. For example, for a category-dtype Series,
        ``to_numpy()`` will return a NumPy array and the categorical dtype
        will be lost.

        For NumPy dtypes, this will be a reference to the actual data stored
        in this Series or Index (assuming ``copy=False``). Modifying the result
        in place will modify the data stored in the Series or Index (not that
        we recommend doing that).

        For extension types, ``to_numpy()`` *may* require copying data and
        coercing the result to a NumPy type (possibly object), which may be
        expensive. When you need a no-copy reference to the underlying data,
        :attr:`Series.array` should be used instead.

        This table lays out the different dtypes and default return types of
        ``to_numpy()`` for various dtypes within pandas.

        ================== ================================
        dtype              array type
        ================== ================================
        category[T]        ndarray[T] (same dtype as input)
        period             ndarray[object] (Periods)
        interval           ndarray[object] (Intervals)
        IntegerNA          ndarray[object]
        datetime64[ns]     datetime64[ns]
        datetime64[ns, tz] ndarray[object] (Timestamps)
        ================== ================================

        Examples
        --------
        >>> ser = pd.Series(pd.Categorical(['a', 'b', 'a']))
        >>> ser.to_numpy()
        array(['a', 'b', 'a'], dtype=object)

        Specify the `dtype` to control how datetime-aware data is represented.
        Use ``dtype=object`` to return an ndarray of pandas :class:`Timestamp`
        objects, each with the correct ``tz``.

        >>> ser = pd.Series(pd.date_range('2000', periods=2, tz="CET"))
        >>> ser.to_numpy(dtype=object)
        array([Timestamp('2000-01-01 00:00:00+0100', tz='CET'),
               Timestamp('2000-01-02 00:00:00+0100', tz='CET')],
              dtype=object)

        Or ``dtype='datetime64[ns]'`` to return an ndarray of native
        datetime64 values. The values are converted to UTC and the timezone
        info is dropped.

        >>> ser.to_numpy(dtype="datetime64[ns]")
        ... # doctest: +ELLIPSIS
        array(['1999-12-31T23:00:00.000000000', '2000-01-01T23:00:00...'],
              dtype='datetime64[ns]')
        )rš   r›   r   z/to_numpy() got an unexpected keyword argument 'rc   )rŒ   )r   rŒ   r˜   Úto_numpyrn   ÚkeysÚ	TypeErrorrp   Úasarrayr�   ÚlibÚ
no_defaultrš   Z
asanyarrayr!   )r>   rŒ   rš   r›   rˆ   r„   Úresultr?   r?   r@   rœ   ¬  s    c

ÿ
zIndexOpsMixin.to_numpyc                 C  s   | j  S rl   )r—   r=   r?   r?   r@   Úempty  s    zIndexOpsMixin.emptyT©Úskipnac                 O  s&   t  |¡ t  ||¡ tj| j|d�S )a  
        Return the maximum value of the Index.

        Parameters
        ----------
        axis : int, optional
            For compatibility with NumPy. Only 0 or None are allowed.
        skipna : bool, default True
            Exclude NA/null values when showing the result.
        *args, **kwargs
            Additional arguments and keywords for compatibility with NumPy.

        Returns
        -------
        scalar
            Maximum value.

        See Also
        --------
        Index.min : Return the minimum value in an Index.
        Series.max : Return the maximum value in a Series.
        DataFrame.max : Return the maximum values in a DataFrame.

        Examples
        --------
        >>> idx = pd.Index([3, 2, 1])
        >>> idx.max()
        3

        >>> idx = pd.Index(['c', 'b', 'a'])
        >>> idx.max()
        'c'

        For a MultiIndex, the maximum is determined lexicographically.

        >>> idx = pd.MultiIndex.from_product([('a', 'b'), (2, 1)])
        >>> idx.max()
        ('b', 2)
        r¤   )rŽ   Úvalidate_minmax_axisZvalidate_maxr$   Znanmaxr�   ©r>   rv   r¥   r‡   rˆ   r?   r?   r@   Úmax#  s    (
zIndexOpsMixin.maxr¨   ÚminÚlargest)ÚopZopposerf   )r¥   rD   c                 O  sX   | j }t |¡ t |||¡}t|tƒrF|s<| ¡  ¡ r<dS | ¡ S nt	j
||d�S dS )ab  
        Return int position of the {value} value in the Series.

        If the {op}imum is achieved in multiple locations,
        the first row position is returned.

        Parameters
        ----------
        axis : {{None}}
            Unused. Parameter needed for compatibility with DataFrame.
        skipna : bool, default True
            Exclude NA/null values when showing the result.
        *args, **kwargs
            Additional arguments and keywords for compatibility with NumPy.

        Returns
        -------
        int
            Row position of the {op}imum value.

        See Also
        --------
        Series.arg{op} : Return position of the {op}imum value.
        Series.arg{oppose} : Return position of the {oppose}imum value.
        numpy.ndarray.arg{op} : Equivalent method for numpy arrays.
        Series.idxmax : Return index label of the maximum values.
        Series.idxmin : Return index label of the minimum values.

        Examples
        --------
        Consider dataset containing cereal calories

        >>> s = pd.Series({{'Corn Flakes': 100.0, 'Almond Delight': 110.0,
        ...                'Cinnamon Toast Crunch': 120.0, 'Cocoa Puff': 110.0}})
        >>> s
        Corn Flakes              100.0
        Almond Delight           110.0
        Cinnamon Toast Crunch    120.0
        Cocoa Puff               110.0
        dtype: float64

        >>> s.argmax()
        2
        >>> s.argmin()
        0

        The maximum cereal calories is the third element and
        the minimum cereal calories is the first element,
        since series is zero-indexed.
        ry   r¤   N)r�   rŽ   r¦   Zvalidate_argmax_with_skipnarm   r+   r!   ÚanyÚargmaxr$   Z	nanargmax©r>   rv   r¥   r‡   rˆ   Zdelegater?   r?   r@   r­   O  s    4


 ÿzIndexOpsMixin.argmaxc                 O  s&   t  |¡ t  ||¡ tj| j|d�S )a  
        Return the minimum value of the Index.

        Parameters
        ----------
        axis : {None}
            Dummy argument for consistency with Series.
        skipna : bool, default True
            Exclude NA/null values when showing the result.
        *args, **kwargs
            Additional arguments and keywords for compatibility with NumPy.

        Returns
        -------
        scalar
            Minimum value.

        See Also
        --------
        Index.max : Return the maximum value of the object.
        Series.min : Return the minimum value in a Series.
        DataFrame.min : Return the minimum values in a DataFrame.

        Examples
        --------
        >>> idx = pd.Index([3, 2, 1])
        >>> idx.min()
        1

        >>> idx = pd.Index(['c', 'b', 'a'])
        >>> idx.min()
        'a'

        For a MultiIndex, the minimum is determined lexicographically.

        >>> idx = pd.MultiIndex.from_product([('a', 'b'), (2, 1)])
        >>> idx.min()
        ('a', 1)
        r¤   )rŽ   r¦   Zvalidate_minr$   Znanminr�   r§   r?   r?   r@   r©   “  s    (
zIndexOpsMixin.minÚsmallestc                 O  sX   | j }t |¡ t |||¡}t|tƒrF|s<| ¡  ¡ r<dS | ¡ S nt	j
||d�S d S )Nry   r¤   )r�   rŽ   r¦   Zvalidate_argmin_with_skipnarm   r+   r!   r¬   Úargminr$   Z	nanargminr®   r?   r?   r@   r°   ¿  s    


 ÿzIndexOpsMixin.argminc                 C  s
   | j  ¡ S )a–  
        Return a list of the values.

        These are each a scalar type, which is a Python scalar
        (for str, int, float) or a pandas scalar
        (for Timestamp/Timedelta/Interval/Period)

        Returns
        -------
        list

        See Also
        --------
        numpy.ndarray.tolist : Return the array as an a.ndim-levels deep
            nested list of Python scalars.
        )r�   rŠ   r=   r?   r?   r@   rŠ   Ñ  s    zIndexOpsMixin.tolistc                 C  s2   t | jtjƒst| jƒS t| jjt| jjƒƒS dS )a  
        Return an iterator of the values.

        These are each a scalar type, which is a Python scalar
        (for str, int, float) or a pandas scalar
        (for Timestamp/Timedelta/Interval/Period)

        Returns
        -------
        iterator
        N)	rm   r�   rp   rq   r“   Úmapr•   Úranger—   r=   r?   r?   r@   Ú__iter__æ  s    
zIndexOpsMixin.__iter__c                 C  s   t t| ƒ ¡ ƒS )zc
        Return True if there are any NaNs.

        Enables various performance speedups.
        )r™   r!   r¬   r=   r?   r?   r@   Úhasnansù  s    	zIndexOpsMixin.hasnansznpt.NDArray[np.bool_]c                 C  s
   t | jƒS rl   )r!   r�   r=   r?   r?   r@   r!     s    zIndexOpsMixin.isnar   )rv   r¥   Únumeric_onlyÚfilter_typerB   ©Únamec          	      K  s>   t | |dƒ}|dkr,tt| ƒj› d|› �ƒ‚|f d|i|—ŽS )zA
        Perform the reduction type operation if we can.
        Nz cannot perform the operation r¥   )rR   rž   r<   rX   )	r>   r«   r¸   rv   r¥   rµ   r¶   Úkwdsr†   r?   r?   r@   Ú_reduce  s    ÿzIndexOpsMixin._reducec           	        sB  t |ƒr<t|tƒr.t|dƒr.|‰ ‡ fdd„}nt|tjd�}t|tƒr¼|dkrbd|› d�}t|ƒ‚|dkrx||j	 
¡  }t| jƒr˜td	| jƒ}| |¡S | j}|j	 |¡}t |j|¡}|S t| jƒrît| jd
ƒrî| j}|dk	rät‚dd„ }nF| j t¡}|dk�rdd„ }n&|dk�r tj}nd|› d�}t|ƒ‚|||ƒ}|S )a—  
        An internal function that maps values using the input
        correspondence (which can be a dict, Series, or function).

        Parameters
        ----------
        mapper : function, dict, or Series
            The input correspondence object
        na_action : {None, 'ignore'}
            If 'ignore', propagate NA values, without passing them to the
            mapping function

        Returns
        -------
        Union[Index, MultiIndex], inferred
            The output of the mapping function applied to the index.
            If the function returns a tuple with more than one element
            a MultiIndex will be returned.
        Ú__missing__c                   s   ˆ |  S rl   r?   )Úx©Zdict_with_defaultr?   r@   Ú<lambda>9  ó    z+IndexOpsMixin._map_values.<locals>.<lambda>)Zdtype_if_empty)NÚignorez+na_action must either be 'ignore' or None, z was passedrÀ   r1   r±   Nc                 S  s
   |   |¡S rl   )r±   ©ÚvaluesÚfr?   r?   r@   r¾   i  r¿   c                 S  s   t  | |t| ƒ tj¡¡S rl   )r    Zmap_infer_maskr!   Úviewrp   Zuint8rÁ   r?   r?   r@   r¾   m  s     ÿ)r   rm   ÚdictrJ   r,   rp   Zfloat64r    r”   ÚindexZnotnar   rŒ   r	   r�   r±   Zget_indexerr#   Ztake_ndr   ÚNotImplementedErrorZastyperE   r    Z	map_infer)	r>   ZmapperZ	na_actionÚmsgÚcatrÂ   ZindexerÚ
new_valuesZmap_fr?   r½   r@   Ú_map_values  sJ     ÿ

ÿ






ÿ
zIndexOpsMixin._map_valuesr2   )Ú	normalizeÚsortÚ	ascendingÚdropnarD   c                 C  s   t | |||||d�S )aÏ  
        Return a Series containing counts of unique values.

        The resulting object will be in descending order so that the
        first element is the most frequently-occurring element.
        Excludes NA values by default.

        Parameters
        ----------
        normalize : bool, default False
            If True then the object returned will contain the relative
            frequencies of the unique values.
        sort : bool, default True
            Sort by frequencies.
        ascending : bool, default False
            Sort in ascending order.
        bins : int, optional
            Rather than count values, group them into half-open bins,
            a convenience for ``pd.cut``, only works with numeric data.
        dropna : bool, default True
            Don't include counts of NaN.

        Returns
        -------
        Series

        See Also
        --------
        Series.count: Number of non-NA elements in a Series.
        DataFrame.count: Number of non-NA elements in a DataFrame.
        DataFrame.value_counts: Equivalent method on DataFrames.

        Examples
        --------
        >>> index = pd.Index([3, 1, 2, 3, 4, np.nan])
        >>> index.value_counts()
        3.0    2
        1.0    1
        2.0    1
        4.0    1
        dtype: int64

        With `normalize` set to `True`, returns the relative frequency by
        dividing all values by the sum of values.

        >>> s = pd.Series([3, 1, 2, 3, 4, np.nan])
        >>> s.value_counts(normalize=True)
        3.0    0.4
        1.0    0.2
        2.0    0.2
        4.0    0.2
        dtype: float64

        **bins**

        Bins can be useful for going from a continuous variable to a
        categorical variable; instead of counting unique
        apparitions of values, divide the index in the specified
        number of half-open bins.

        >>> s.value_counts(bins=3)
        (0.996, 2.0]    2
        (2.0, 3.0]      2
        (3.0, 4.0]      1
        dtype: int64

        **dropna**

        With `dropna` set to `False` we can also see NaN index values.

        >>> s.value_counts(dropna=False)
        3.0    2
        1.0    1
        2.0    1
        4.0    1
        NaN    1
        dtype: int64
        )rÍ   rÎ   rÌ   ÚbinsrÏ   )r)   )r>   rÌ   rÍ   rÎ   rÐ   rÏ   r?   r?   r@   r)   ~  s    VúzIndexOpsMixin.value_countsc                 C  sV   | j }t|tjƒsJ| ¡ }t| jtjƒrR| jjdkrRt| tƒrRt |¡}nt	|ƒ}|S )N)ÚmÚM)
r�   rm   rp   rq   r7   rŒ   Úkindr    rŸ   r(   )r>   rÂ   r¢   r?   r?   r@   r7   Ý  s    ÿ
ÿþzIndexOpsMixin.unique)rÏ   rD   c                 C  s   |   ¡ }|rt|ƒ}t|ƒS )aŒ  
        Return number of unique elements in the object.

        Excludes NA values by default.

        Parameters
        ----------
        dropna : bool, default True
            Don't include NaN in the count.

        Returns
        -------
        int

        See Also
        --------
        DataFrame.nunique: Method nunique for DataFrame.
        Series.count: Count non-NA/null observations in the Series.

        Examples
        --------
        >>> s = pd.Series([1, 3, 5, 7, 7])
        >>> s
        0    1
        1    3
        2    5
        3    7
        4    7
        dtype: int64

        >>> s.nunique()
        4
        )r7   r"   rw   )r>   rÏ   Zuniqsr?   r?   r@   Únuniqueí  s    "zIndexOpsMixin.nuniquec                 C  s   | j dd�t| ƒkS )zr
        Return boolean if values in the object are unique.

        Returns
        -------
        bool
        F)rÏ   )rÔ   rw   r=   r?   r?   r@   Ú	is_unique  s    	zIndexOpsMixin.is_uniquec                 C  s   t jdttt ¡ ƒd� | jS )a$  
        Return boolean if values in the object are monotonically increasing.

        .. deprecated:: 1.5.0
            is_monotonic is deprecated and will be removed in a future version.
            Use is_monotonic_increasing instead.

        Returns
        -------
        bool
        zhis_monotonic is deprecated and will be removed in a future version. Use is_monotonic_increasing instead.)Ú
stacklevel)ÚwarningsÚwarnÚFutureWarningr   ÚinspectÚcurrentframeÚis_monotonic_increasingr=   r?   r?   r@   Úis_monotonic  s    
üzIndexOpsMixin.is_monotonicc                 C  s   ddl m} || ƒjS )z„
        Return boolean if values in the object are monotonically increasing.

        Returns
        -------
        bool
        r   ©ÚIndex)Úpandasrß   rÜ   ©r>   rß   r?   r?   r@   rÜ   4  s    	z%IndexOpsMixin.is_monotonic_increasingc                 C  s   ddl m} || ƒjS )z„
        Return boolean if values in the object are monotonically decreasing.

        Returns
        -------
        bool
        r   rÞ   )rà   rß   Úis_monotonic_decreasingrá   r?   r?   r@   râ   A  s    	z%IndexOpsMixin.is_monotonic_decreasing)rQ   rD   c                 C  sR   t | jdƒr| jj|d�S | jj}|rNt| ƒrNtsNttj| j	ƒ}|t
 |¡7 }|S )aN  
        Memory usage of the values.

        Parameters
        ----------
        deep : bool, default False
            Introspect the data deeply, interrogate
            `object` dtypes for system-level memory consumption.

        Returns
        -------
        bytes used

        See Also
        --------
        numpy.ndarray.nbytes : Total bytes consumed by the elements of the
            array.

        Notes
        -----
        Memory usage does not include memory consumed by elements that
        are not components of the array if deep=False or if used on PyPy
        rO   rP   )rJ   r˜   rO   r–   r   r   r	   rp   rq   r�   r    Zmemory_usage_of_objects)r>   rQ   ÚvrÂ   r?   r?   r@   Ú_memory_usageN  s    zIndexOpsMixin._memory_usager5   z”            sort : bool, default False
                Sort `uniques` and shuffle `codes` to maintain the
                relationship.
            )rÂ   ÚorderZ	size_hintrÍ   zint | lib.NoDefaultzbool | lib.NoDefault©rÍ   Úna_sentinelÚuse_na_sentinelc                 C  s   t j| |||d�S )Nræ   )r#   Ú	factorize)r>   rÍ   rç   rè   r?   r?   r@   ré   q  s       ÿzIndexOpsMixin.factorizea  
        Find indices where elements should be inserted to maintain order.

        Find the indices into a sorted {klass} `self` such that, if the
        corresponding elements in `value` were inserted before the indices,
        the order of `self` would be preserved.

        .. note::

            The {klass} *must* be monotonically sorted, otherwise
            wrong locations will likely be returned. Pandas does *not*
            check this for you.

        Parameters
        ----------
        value : array-like or scalar
            Values to insert into `self`.
        side : {{'left', 'right'}}, optional
            If 'left', the index of the first suitable location found is given.
            If 'right', return the last such index.  If there is no suitable
            index, return either 0 or N (where N is the length of `self`).
        sorter : 1-D array-like, optional
            Optional array of integer indices that sort `self` into ascending
            order. They are typically the result of ``np.argsort``.

        Returns
        -------
        int or array of int
            A scalar or array of insertion points with the
            same shape as `value`.

        See Also
        --------
        sort_values : Sort by the values along either axis.
        numpy.searchsorted : Similar method from NumPy.

        Notes
        -----
        Binary search is used to find the required insertion points.

        Examples
        --------
        >>> ser = pd.Series([1, 2, 3])
        >>> ser
        0    1
        1    2
        2    3
        dtype: int64

        >>> ser.searchsorted(4)
        3

        >>> ser.searchsorted([0, 4])
        array([0, 3])

        >>> ser.searchsorted([1, 3], side='left')
        array([0, 2])

        >>> ser.searchsorted([1, 3], side='right')
        array([1, 3])

        >>> ser = pd.Series(pd.to_datetime(['3/11/2000', '3/12/2000', '3/13/2000']))
        >>> ser
        0   2000-03-11
        1   2000-03-12
        2   2000-03-13
        dtype: datetime64[ns]

        >>> ser.searchsorted('3/14/2000')
        3

        >>> ser = pd.Categorical(
        ...     ['apple', 'bread', 'bread', 'cheese', 'milk'], ordered=True
        ... )
        >>> ser
        ['apple', 'bread', 'bread', 'cheese', 'milk']
        Categories (4, object): ['apple' < 'bread' < 'cheese' < 'milk']

        >>> ser.searchsorted('bread')
        1

        >>> ser.searchsorted(['bread'], side='right')
        array([3])

        If the values are not monotonically sorted, wrong locations
        may be returned:

        >>> ser = pd.Series([2, 1, 3])
        >>> ser
        0    2
        1    1
        2    3
        dtype: int64

        >>> ser.searchsorted(1)  # doctest: +SKIP
        0  # wrong result, correct would be 1
        Úsearchsorted.znpt._ScalarLike_cozLiteral[('left', 'right')]r/   znp.intp)rf   ÚsideÚsorterrD   c                 C  s   d S rl   r?   ©r>   rf   rë   rì   r?   r?   r@   rê   ï  s    zIndexOpsMixin.searchsortedznpt.ArrayLike | ExtensionArrayznpt.NDArray[np.intp]c                 C  s   d S rl   r?   rí   r?   r?   r@   rê   ü  s    rß   )r6   Úleftz$NumpyValueArrayLike | ExtensionArrayznpt.NDArray[np.intp] | np.intpc                 C  s4   | j }t|tjƒs"|j|||d�S tj||||d�S )N)rë   rì   )r�   rm   rp   rq   rê   r#   )r>   rf   rë   rì   rÂ   r?   r?   r@   rê     s    üÚfirstc                 C  s   | j |d�}| |  S ©N)Úkeep)Ú_duplicated)r>   rñ   r'   r?   r?   r@   Údrop_duplicates  s    zIndexOpsMixin.drop_duplicatesz!Literal[('first', 'last', False)])rñ   rD   c                 C  s   t | j|d�S rð   )r'   r�   )r>   rñ   r?   r?   r@   rò     s    zIndexOpsMixin._duplicatedc              	   C  sj   t  | |¡}| j}t|ddd�}t  ||j¡}t|ƒ}tjdd�� t  	|||¡}W 5 Q R X | j
||d�S )NT)Zextract_numpyZextract_rangerÀ   )Úallr·   )r%   Zget_op_result_namer�   r.   Zmaybe_prepare_scalar_for_opr�   r-   rp   ZerrstateZarithmetic_opÚ_construct_result)r>   Úotherr«   Zres_nameZlvaluesZrvaluesr¢   r?   r?   r@   Ú_arith_method$  s    zIndexOpsMixin._arith_methodc                 C  s   t | ƒ‚dS )z~
        Construct an appropriately-wrapped result from the ArrayLike result
        of an arithmetic-like operation.
        Nr   )r>   r¢   r¸   r?   r?   r@   rõ   1  s    zIndexOpsMixin._construct_result)NT)NT)NT)NT)N)FTFNT)T)F)..)..)rî   N)rï   )rï   )9rX   rY   rZ   r[   Z__array_priority__Ú	frozensetr‹   r\   r]   rŒ   r�   r�   ÚTr�   r‘   rt   r•   r–   r—   r˜   r    r¡   rœ   r£   r¨   r   r­   r©   r°   rŠ   Zto_listr³   r   r´   r!   rº   r
   rË   r)   r7   rÔ   rÕ   rÝ   rÜ   râ   rä   r#   ré   ÚtextwrapÚdedentr3   r   rê   ró   rò   r÷   rõ   r?   r?   r?   r@   r4     sÎ   
ÿþBüs,C,
øc     ú_'
#ÿûüþÿg  ü  ü  ü
 ÿ)Tr[   Ú
__future__r   rÚ   rú   Útypingr   r   r   r   r   r   r	   r
   r   r×   Únumpyrp   Zpandas._libs.libZ_libsr    Zpandas._typingr   r   r   r   r   r   Zpandas.compatr   Zpandas.compat.numpyr   rŽ   Zpandas.errorsr   Zpandas.util._decoratorsr   r   Zpandas.util._exceptionsr   Zpandas.core.dtypes.commonr   r   r   r   r   Zpandas.core.dtypes.genericr   r   r    Zpandas.core.dtypes.missingr!   r"   Zpandas.corer#   r$   r%   Zpandas.core.accessorr&   Zpandas.core.algorithmsr'   r(   r)   Zpandas.core.arrayliker*   Zpandas.core.arraysr+   Zpandas.core.constructionr,   r-   r.   r/   r0   rà   r1   r2   r3   r\   Z_indexops_doc_kwargsr8   r:   r_   rg   r4   r?   r?   r?   r@   Ú<module>   sH   , ü/"[