§
    
�’j+F  ã                  óx  — d Z ddlmZ ddlZddlmZmZ ddlZddlm	Z	 ddl
mZ erddlmZ ddlmZ dd	lmZ dd
lmZ  G d„ d¦  «        Z G d„ d¦  «        Zdd„ dfd+d„Z G d„ d¦  «        ZeZd,d#„Zd$Z e	d%¦  «        d-d&„¦   «         Zd'Z e	d%¦  «        d-d(„¦   «         Zd)Z e	d%¦  «        d-d*„¦   «         ZdS ).z†

accessor.py contains base classes for implementing accessor properties
that can be mixed into or pinned onto other pandas classes.

é    )ÚannotationsN)ÚTYPE_CHECKINGÚfinal)Ú
set_module)Úfind_stack_level)ÚCallable)ÚTypeT©ÚIndex)ÚNDFramec                  ó~   ‡ — e Zd ZU  e¦   «         Zded<    e¦   «         Zded<   ed
d„¦   «         Z	d
d„Z
dˆ fd	„Zˆ xZS )ÚDirNamesMixinúset[str]Ú
_accessorszfrozenset[str]Ú_hidden_attrsÚreturnc                ó    — | j         | j        z  S )z:
        Delete unwanted __dir__ for this object.
        )r   r   ©Úselfs    úBC:\Projects\DSCons\.venv\Lib\site-packages\pandas\core\accessor.pyÚ_dir_deletionszDirNamesMixin._dir_deletions#   s   € ð
 Œ Ô!3Ñ3Ð3ó    c                ó*   ‡ — ˆ fd„‰ j         D ¦   «         S )z9
        Add additional __dir__ for this object.
        c                ó4   •— h | ]}t          ‰|¦  «        ¯|’ŒS © )Úhasattr)Ú.0Úaccessorr   s     €r   ú	<setcomp>z/DirNamesMixin._dir_additions.<locals>.<setcomp>.   s(   ø€ ÐTÐTÐT˜X½GÀDÈ(Ñ<SÔ<SÐT�ÐTÐTÐTr   )r   r   s   `r   Ú_dir_additionszDirNamesMixin._dir_additions*   s"   ø€ ð UÐTÐTÐT¨¬ÐTÑTÔTÐTr   ú	list[str]c                óÔ   •— t          t          ¦   «                              ¦   «         ¦  «        }||                      ¦   «         z
  |                      ¦   «         z  }t          |¦  «        S )z€
        Provide method name lookup and completion.

        Notes
        -----
        Only provide 'public' methods.
        )ÚsetÚsuperÚ__dir__r   r    Úsorted)r   ÚrvÚ	__class__s     €r   r%   zDirNamesMixin.__dir__0   sS   ø€ õ •‘”—’Ñ"Ô"Ñ#Ô#ˆØ�4×&Ò&Ñ(Ô(Ñ(¨D×,?Ò,?Ñ,AÔ,AÑAˆÝ�b‰zŒzÐr   )r   r   )r   r!   )Ú__name__Ú
__module__Ú__qualname__r#   r   Ú__annotations__Ú	frozensetr   r   r   r    r%   Ú__classcell__)r(   s   @r   r   r      s£   ø€ € € € € € Ø˜3™5œ5€JÐ Ð Ð Ñ Ø$- I¡K¤K€MÐ/Ð/Ð/Ñ/à
ð4ð 4ð 4ñ „Uð4ðUð Uð Uð Uð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
r   r   c                  óL   — e Zd ZdZdd„Zdd„Zdd„Zed	d
„ dfdd„¦   «         ZdS )ÚPandasDelegatez@
    Abstract base class for delegating methods/properties.
    ÚnameÚstrc                ó&   — t          d|› �¦  «        ‚)NzYou cannot access the property ©Ú	TypeError©r   r1   ÚargsÚkwargss       r   Ú_delegate_property_getz%PandasDelegate._delegate_property_getB   s   € ÝÐ@¸$Ð@Ð@ÑAÔAÐAr   r   ÚNonec                ó(   — t          d|› d�¦  «        ‚)NzThe property z cannot be setr4   )r   r1   Úvaluer7   r8   s        r   Ú_delegate_property_setz%PandasDelegate._delegate_property_setE   s   € ÝÐ<¨Ð<Ð<Ð<Ñ=Ô=Ð=r   c                ó&   — t          d|› �¦  «        ‚)NzYou cannot call method r4   r6   s       r   Ú_delegate_methodzPandasDelegate._delegate_methodH   s   € ÝÐ8°$Ð8Ð8Ñ9Ô9Ð9r   Fc                ó   — | S ©Nr   ©Úxs    r   ú<lambda>zPandasDelegate.<lambda>R   s   € ¸1€ r   TÚ	accessorsr!   ÚtypÚ	overwriteÚboolÚaccessor_mappingúCallable[[str], str]Úraise_on_missingc                óê   ‡‡— dˆˆfd„}dˆˆfd„}|D ]_}	|st          ‰ ‰|	¦  «        d¦  «        €Œ|dk    r ||	¦  «        }
n ||	¦  «        }
|st          | |	¦  «        st          | |	|
¦  «         Œ`dS )aì  
        Add accessors to cls from the delegate class.

        Parameters
        ----------
        cls
            Class to add the methods/properties to.
        delegate
            Class to get methods/properties and docstrings.
        accessors : list of str
            List of accessors to add.
        typ : {'property', 'method'}
        overwrite : bool, default False
            Overwrite the method/property in the target class if it exists.
        accessor_mapping: Callable, default lambda x: x
            Callable to map the delegate's function to the cls' function.
        raise_on_missing: bool, default True
            Raise if an accessor does not exist on delegate.
            False skips the missing accessor.
        r1   r2   c           
     ó’   •‡ — ˆ fd„}ˆ fd„}‰ |_         ‰ |_         t          ||t          ‰ ‰‰ ¦  «        ¦  «        j        ¬¦  «        S )Nc                ó.   •— |                       ‰¦  «        S rA   )r9   )r   r1   s    €r   Ú_getterz[PandasDelegate._add_delegate_accessors.<locals>._create_delegator_property.<locals>._getterk   s   ø€ Ø×2Ò2°4Ñ8Ô8Ð8r   c                ó0   •— |                       ‰|¦  «        S rA   )r=   )r   Ú
new_valuesr1   s     €r   Ú_setterz[PandasDelegate._add_delegate_accessors.<locals>._create_delegator_property.<locals>._settern   s   ø€ Ø×2Ò2°4¸ÑDÔDÐDr   )ÚfgetÚfsetÚdoc)r)   ÚpropertyÚgetattrÚ__doc__)r1   rO   rR   rI   Údelegates   `  €€r   Ú_create_delegator_propertyzJPandasDelegate._add_delegate_accessors.<locals>._create_delegator_propertyj   s†   øø€ ð9ð 9ð 9ð 9ð 9ðEð Eð Eð Eð Eð  $ˆGÔØ#ˆGÔåØØÝ˜HÐ&6Ð&6°tÑ&<Ô&<Ñ=Ô=ÔEðñ ô ð r   c                óz   •‡ — t          ‰ ‰‰ ¦  «        ¦  «        }t          j        |¦  «        ˆ fd„¦   «         }|S )Nc                ó&   •—  | j         ‰g|¢R i |¤ŽS rA   )r?   )r   r7   r8   r1   s      €r   ÚfzSPandasDelegate._add_delegate_accessors.<locals>._create_delegator_method.<locals>.f}   s&   ø€ à,�tÔ,¨TÐC°DÐCÐCÐC¸FÐCÐCÐCr   )rW   Ú	functoolsÚwraps)r1   Úmethodr]   rI   rY   s   `  €€r   Ú_create_delegator_methodzHPandasDelegate._add_delegate_accessors.<locals>._create_delegator_methodz   sY   øø€ Ý˜XÐ'7Ð'7¸Ñ'=Ô'=Ñ>Ô>ˆFåŒ_˜VÑ$Ô$ðDð Dð Dð Dñ %Ô$ðDð ˆHr   NrV   ©r1   r2   )rW   r   Úsetattr)ÚclsrY   rE   rF   rG   rI   rK   rZ   ra   r1   r]   s    `   `     r   Ú_add_delegate_accessorsz&PandasDelegate._add_delegate_accessorsK   sé   øø€ ð>	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð ð 	&ð 	&ˆDà$ðå˜HÐ&6Ð&6°tÑ&<Ô&<¸dÑCÔCÐKàà�jÒ Ð Ø.Ð.¨tÑ4Ô4��à,Ð,¨TÑ2Ô2�ð ð &¥¨¨TÑ 2Ô 2ð &Ý˜˜T 1Ñ%Ô%Ð%øð	&ð 	&r   Nrb   ©r1   r2   r   r:   )rE   r!   rF   r2   rG   rH   rI   rJ   rK   rH   r   r:   )	r)   r*   r+   rX   r9   r=   r?   Úclassmethodre   r   r   r   r0   r0   =   s—   € € € € € ðð ðBð Bð Bð Bð>ð >ð >ð >ð:ð :ð :ð :ð ð  Ø1<°Ø!%ðE&ð E&ð E&ð E&ñ „[ðE&ð E&ð E&r   r0   Fc                ó   — | S rA   r   rB   s    r   rD   rD   ™   s   € °q€ r   TrE   r!   rF   r2   rG   rH   rI   rJ   rK   c                ó&   ‡ ‡‡‡‡‡— ˆˆˆ ˆˆˆfd„}|S )aÖ  
    Add delegated names to a class using a class decorator.  This provides
    an alternative usage to directly calling `_add_delegate_accessors`
    below a class definition.

    Parameters
    ----------
    delegate : object
        The class to get methods/properties & docstrings.
    accessors : Sequence[str]
        List of accessor to add.
    typ : {'property', 'method'}
    overwrite : bool, default False
       Overwrite the method/property in the target class if it exists.
    accessor_mapping: Callable, default lambda x: x
        Callable to map the delegate's function to the cls' function.
    raise_on_missing: bool, default True
        Raise if an accessor does not exist on delegate.
        False skips the missing accessor.

    Returns
    -------
    callable
        A class decorator.

    Examples
    --------
    @delegate_names(Categorical, ["categories", "ordered"], "property")
    class CategoricalAccessor(PandasDelegate):
        [...]
    c                ó>   •— |                       ‰‰‰‰‰‰¬¦  «         | S )N)rG   rI   rK   )re   )rd   rI   rE   rY   rG   rK   rF   s    €€€€€€r   Úadd_delegate_accessorsz.delegate_names.<locals>.add_delegate_accessors¼   s9   ø€ Ø×#Ò#ØØØØØ-Ø-ð 	$ñ 	
ô 	
ð 	
ð ˆ
r   r   )rY   rE   rF   rG   rI   rK   rk   s   `````` r   Údelegate_namesrl   ”   sC   øøøøøø€ ðP	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð "Ð!r   c                  ó    — e Zd ZdZd	d„Zd„ ZdS )
ÚAccessora™  
    Custom property-like object.

    A descriptor for accessors.

    Parameters
    ----------
    name : str
        Namespace that will be accessed under, e.g. ``df.foo``.
    accessor : cls
        Class with the extension methods.

    Notes
    -----
    For accessor, The class's __init__ method assumes that one of
    ``Series``, ``DataFrame`` or ``Index`` as the
    single argument ``data``.
    r1   r2   r   r:   c                ó"   — || _         || _        d S rA   )Ú_nameÚ	_accessor)r   r1   r   s      r   Ú__init__zAccessor.__init__Þ   s   € ØˆŒ
Ø!ˆŒˆˆr   c                ó>   — |€| j         S |                       |¦  «        S rA   )rq   )r   Úobjrd   s      r   Ú__get__zAccessor.__get__â   s!   € Øˆ;à”>Ð!Ø�~Š~˜cÑ"Ô"Ð"r   Nrf   )r)   r*   r+   rX   rr   ru   r   r   r   rn   rn   Ê   sA   € € € € € ðð ð&"ð "ð "ð "ð#ð #ð #ð #ð #r   rn   r1   rd   útype[NDFrame | Index]r   úCallable[[TypeT], TypeT]c                ó   ‡ ‡— dˆˆ fd„}|S )a™  
    Register a custom accessor on objects.

    Parameters
    ----------
    name : str
        Name under which the accessor should be registered. A warning is issued
        if this name conflicts with a preexisting attribute.

    Returns
    -------
    callable
        A class decorator.

    See Also
    --------
    register_dataframe_accessor : Register a custom accessor on DataFrame objects.
    register_series_accessor : Register a custom accessor on Series objects.
    register_index_accessor : Register a custom accessor on Index objects.

    Notes
    -----
    This function allows you to register a custom-defined accessor class
    for pandas objects (DataFrame, Series, or Index).
    The requirements for the accessor class are as follows:

    * Must contain an init method that:

      * accepts a single object

      * raises an AttributeError if the object does not have correctly
        matching inputs for the accessor

    * Must contain a method for each access pattern.

      * The methods should be able to take any argument signature.

      * Accessible using the @property decorator if no additional arguments are
        needed.

    r   r	   r   c           	     óþ   •— t          ‰‰¦  «        r2t          j        d| ›d‰›d‰›d�t          t	          ¦   «         ¬¦  «         t          ‰‰t          ‰| ¦  «        ¦  «         ‰j                             ‰¦  «         | S )Nzregistration of accessor z under name z
 for type z: is overriding a preexisting attribute with the same name.)Ú
stacklevel)	r   ÚwarningsÚwarnÚUserWarningr   rc   rn   r   Úadd)r   rd   r1   s    €€r   Ú	decoratorz%_register_accessor.<locals>.decorator  s¥   ø€ Ý�3˜ÑÔð 	ÝŒMð1¨Hð 1ð 1Øð1ð 1Ø%(ð1ð 1ð 1õ Ý+Ñ-Ô-ðñ ô ð õ 	��T�8 D¨(Ñ3Ô3Ñ4Ô4Ð4ØŒ×Ò˜4Ñ Ô Ð Øˆr   )r   r	   r   r	   r   )r1   rd   r   s   `` r   Ú_register_accessorr€   î   s0   øø€ ðZð ð ð ð ð ð ð Ðr   aä  
An accessor that only accepts integers could
have a class defined like this:

>>> @pd.api.extensions.register_dataframe_accessor("int_accessor")
... class IntAccessor:
...     def __init__(self, pandas_obj):
...         if not all(pandas_obj[col].dtype == 'int64' for col in pandas_obj.columns):
...             raise AttributeError("All columns must contain integer values only")
...         self._obj = pandas_obj
...
...     def sum(self):
...         return self._obj.sum()
...
>>> df = pd.DataFrame([[1, 2], ['x', 'y']])
>>> df.int_accessor
Traceback (most recent call last):
...
AttributeError: All columns must contain integer values only.
>>> df = pd.DataFrame([[1, 2], [3, 4]])
>>> df.int_accessor.sum()
0    4
1    6
dtype: int64zpandas.api.extensionsc                ó.   — ddl m} t          | |¦  «        S )a  
    Register a custom accessor on DataFrame objects.

    Parameters
    ----------
    name : str
        Name under which the accessor should be registered. A warning is issued
        if this name conflicts with a preexisting attribute.

    Returns
    -------
    callable
        A class decorator.

    See Also
    --------
    register_dataframe_accessor : Register a custom accessor on DataFrame objects.
    register_series_accessor : Register a custom accessor on Series objects.
    register_index_accessor : Register a custom accessor on Index objects.

    Notes
    -----
    This function allows you to register a custom-defined accessor class for DataFrame.
    The requirements for the accessor class are as follows:

    * Must contain an init method that:

      * accepts a single DataFrame object

      * raises an AttributeError if the DataFrame object does not have correctly
        matching inputs for the accessor

    * Must contain a method for each access pattern.

      * The methods should be able to take any argument signature.

      * Accessible using the @property decorator if no additional arguments are
        needed.

    Examples
    --------
    An accessor that only accepts integers could
    have a class defined like this:

    >>> @pd.api.extensions.register_dataframe_accessor("int_accessor")
    ... class IntAccessor:
    ...     def __init__(self, pandas_obj):
    ...         if not all(
    ...             pandas_obj[col].dtype == "int64" for col in pandas_obj.columns
    ...         ):
    ...             raise AttributeError("All columns must contain integer values only")
    ...         self._obj = pandas_obj
    ...
    ...     def sum(self):
    ...         return self._obj.sum()
    >>> df = pd.DataFrame([[1, 2], ["x", "y"]])
    >>> df.int_accessor
    Traceback (most recent call last):
    ...
    AttributeError: All columns must contain integer values only.
    >>> df = pd.DataFrame([[1, 2], [3, 4]])
    >>> df.int_accessor.sum()
    0    4
    1    6
    dtype: int64
    r   )Ú	DataFrame)Úpandasr‚   r€   )r1   r‚   s     r   Úregister_dataframe_accessorr„   E  s'   € ðH !Ð Ð Ð Ð Ð å˜d IÑ.Ô.Ð.r   a„  
An accessor that only accepts integers could
have a class defined like this:

>>> @pd.api.extensions.register_series_accessor("int_accessor")
... class IntAccessor:
...     def __init__(self, pandas_obj):
...         if not pandas_obj.dtype == 'int64':
...             raise AttributeError("The series must contain integer data only")
...         self._obj = pandas_obj
...
...     def sum(self):
...         return self._obj.sum()
...
>>> df = pd.Series([1, 2, 'x'])
>>> df.int_accessor
Traceback (most recent call last):
...
AttributeError: The series must contain integer data only.
>>> df = pd.Series([1, 2, 3])
>>> df.int_accessor.sum()
6c                ó.   — ddl m} t          | |¦  «        S )aj  
    Register a custom accessor on Series objects.

    Parameters
    ----------
    name : str
        Name under which the accessor should be registered. A warning is issued
        if this name conflicts with a preexisting attribute.

    Returns
    -------
    callable
        A class decorator.

    See Also
    --------
    register_dataframe_accessor : Register a custom accessor on DataFrame objects.
    register_series_accessor : Register a custom accessor on Series objects.
    register_index_accessor : Register a custom accessor on Index objects.

    Notes
    -----
    This function allows you to register a custom-defined accessor class for Series.
    The requirements for the accessor class are as follows:

    * Must contain an init method that:

      * accepts a single Series object

      * raises an AttributeError if the Series object does not have correctly
        matching inputs for the accessor

    * Must contain a method for each access pattern.

      * The methods should be able to take any argument signature.

      * Accessible using the @property decorator if no additional arguments are
        needed.

    Examples
    --------
    An accessor that only accepts integers could
    have a class defined like this:

    >>> @pd.api.extensions.register_series_accessor("int_accessor")
    ... class IntAccessor:
    ...     def __init__(self, pandas_obj):
    ...         if not pandas_obj.dtype == "int64":
    ...             raise AttributeError("The series must contain integer data only")
    ...         self._obj = pandas_obj
    ...
    ...     def sum(self):
    ...         return self._obj.sum()
    >>> df = pd.Series([1, 2, "x"])
    >>> df.int_accessor
    Traceback (most recent call last):
    ...
    AttributeError: The series must contain integer data only.
    >>> df = pd.Series([1, 2, 3])
    >>> df.int_accessor.sum()
    6
    r   )ÚSeries)rƒ   r†   r€   )r1   r†   s     r   Úregister_series_accessorr‡   ¦  s'   € ð@ ÐÐÐÐÐå˜d FÑ+Ô+Ð+r   a[  
An accessor that only accepts integers could
have a class defined like this:

>>> @pd.api.extensions.register_index_accessor("int_accessor")
... class IntAccessor:
...     def __init__(self, pandas_obj):
...         if not all(isinstance(x, int) for x in pandas_obj):
...             raise AttributeError("The index must only be an integer value")
...         self._obj = pandas_obj
...
...     def even(self):
...         return [x for x in self._obj if x % 2 == 0]
>>> df = pd.DataFrame.from_dict(
...     {"row1": {"1": 1, "2": "a"}, "row2": {"1": 2, "2": "b"}}, orient="index"
... )
>>> df.index.int_accessor
Traceback (most recent call last):
...
AttributeError: The index must only be an integer value.
>>> df = pd.DataFrame(
...     {"col1": [1, 2, 3, 4], "col2": ["a", "b", "c", "d"]}, index=[1, 2, 5, 8]
... )
>>> df.index.int_accessor.even()
[2, 8]c                ó.   — ddl m} t          | |¦  «        S )aQ  
    Register a custom accessor on Index objects.

    Parameters
    ----------
    name : str
        Name under which the accessor should be registered. A warning is issued
        if this name conflicts with a preexisting attribute.

    Returns
    -------
    callable
        A class decorator.

    See Also
    --------
    register_dataframe_accessor : Register a custom accessor on DataFrame objects.
    register_series_accessor : Register a custom accessor on Series objects.
    register_index_accessor : Register a custom accessor on Index objects.

    Notes
    -----
    This function allows you to register a custom-defined accessor class for Index.
    The requirements for the accessor class are as follows:

    * Must contain an init method that:

      * accepts a single Index object

      * raises an AttributeError if the Index object does not have correctly
        matching inputs for the accessor

    * Must contain a method for each access pattern.

      * The methods should be able to take any argument signature.

      * Accessible using the @property decorator if no additional arguments are
        needed.

    Examples
    --------
    An accessor that only accepts integers could
    have a class defined like this:

    >>> @pd.api.extensions.register_index_accessor("int_accessor")
    ... class IntAccessor:
    ...     def __init__(self, pandas_obj):
    ...         if not all(isinstance(x, int) for x in pandas_obj):
    ...             raise AttributeError("The index must only be an integer value")
    ...         self._obj = pandas_obj
    ...
    ...     def even(self):
    ...         return [x for x in self._obj if x % 2 == 0]
    >>> df = pd.DataFrame.from_dict(
    ...     {"row1": {"1": 1, "2": "a"}, "row2": {"1": 2, "2": "b"}}, orient="index"
    ... )
    >>> df.index.int_accessor
    Traceback (most recent call last):
    ...
    AttributeError: The index must only be an integer value.
    >>> df = pd.DataFrame(
    ...     {"col1": [1, 2, 3, 4], "col2": ["a", "b", "c", "d"]}, index=[1, 2, 5, 8]
    ... )
    >>> df.index.int_accessor.even()
    [2, 8]
    r   r
   )rƒ   r   r€   )r1   r   s     r   Úregister_index_accessorr‰     s'   € ðH ÐÐÐÐÐå˜d EÑ*Ô*Ð*r   )
rE   r!   rF   r2   rG   rH   rI   rJ   rK   rH   )r1   r2   rd   rv   r   rw   )r1   r2   r   rw   ) rX   Ú
__future__r   r^   Útypingr   r   r{   Úpandas.util._decoratorsr   Úpandas.util._exceptionsr   Úcollections.abcr   Úpandas._typingr	   rƒ   r   Úpandas.core.genericr   r   r0   rl   rn   ÚCachedAccessorr€   Ú_register_df_examplesr„   Ú_register_series_examplesr‡   Ú_register_index_examplesr‰   r   r   r   ú<module>r•      s_  ððð ð #Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð ðð ð ð ð ð ð ð ð €€€ðð ð ð ð ð ð 5Ð 4Ð 4Ð 4Ð 4Ð 4àð ,Ø(Ð(Ð(Ð(Ð(Ð(à$Ð$Ð$Ð$Ð$Ð$àÐÐÐÐÐØ+Ð+Ð+Ð+Ð+Ð+ðð ð ð ð ñ ô ð ð<T&ð T&ð T&ð T&ð T&ñ T&ô T&ð T&ðv Ø-8¨[Ø!ð3"ð 3"ð 3"ð 3"ð 3"ðl#ð #ð #ð #ð #ñ #ô #ð #ðB €ð:ð :ð :ð :ðzÐ ð4 €Ð#Ñ$Ô$ðE/ð E/ð E/ñ %Ô$ðE/ðPÐ ð0 €Ð#Ñ$Ô$ðA,ð A,ð A,ñ %Ô$ðA,ðH
Ð ð6 €Ð#Ñ$Ô$ðE+ð E+ð E+ñ %Ô$ðE+ð E+ð E+r   