o
    �¨Êh&%  ã                   @  s¸   d dl mZ d dlmZ d dlmZmZmZ d dlZ	d dl
mZmZ d dlmZmZ er@d dlmZ d dlmZmZ d d	lmZ G d
d„ dƒZeejƒG dd„ dƒƒZG dd„ dƒZdS )é    )Úannotations)ÚIterable)ÚTYPE_CHECKINGÚLiteralÚcastN)Úcache_readonlyÚdoc)Ú
is_integerÚis_list_like)ÚPositionalIndexer)Ú	DataFrameÚSeries)Úgroupbyc                   @  sl   e Zd ZdZeddd„ƒZdd	d
„Zd dd„Zd!dd„Zd"dd„Z	d#dd„Z
ed$dd„ƒZed$dd„ƒZdS )%ÚGroupByIndexingMixinz<
    Mixin for adding ._positional_selector to GroupBy.
    ÚreturnÚGroupByPositionalSelectorc                 C  s$   t rttj| ƒ}t|ƒS | }t|ƒS )aÌ
  
        Return positional selection for each group.

        ``groupby._positional_selector[i:j]`` is similar to
        ``groupby.apply(lambda x: x.iloc[i:j])``
        but much faster and preserves the original index and order.

        ``_positional_selector[]`` is compatible with and extends :meth:`~GroupBy.head`
        and :meth:`~GroupBy.tail`. For example:

        - ``head(5)``
        - ``_positional_selector[5:-5]``
        - ``tail(5)``

        together return all the rows.

        Allowed inputs for the index are:

        - An integer valued iterable, e.g. ``range(2, 4)``.
        - A comma separated list of integers and slices, e.g. ``5``, ``2, 4``, ``2:4``.

        The output format is the same as :meth:`~GroupBy.head` and
        :meth:`~GroupBy.tail`, namely
        a subset of the ``DataFrame`` or ``Series`` with the index and order preserved.

        Returns
        -------
        Series
            The filtered subset of the original Series.
        DataFrame
            The filtered subset of the original DataFrame.

        See Also
        --------
        DataFrame.iloc : Purely integer-location based indexing for selection by
            position.
        GroupBy.head : Return first n rows of each group.
        GroupBy.tail : Return last n rows of each group.
        GroupBy.nth : Take the nth row from each group if n is an int, or a
            subset of rows, if n is a list of ints.

        Notes
        -----
        - The slice step cannot be negative.
        - If the index specification results in overlaps, the item is not duplicated.
        - If the index specification changes the order of items, then
          they are returned in their original order.
          By contrast, ``DataFrame.iloc`` can change the row order.
        - ``groupby()`` parameters such as as_index and dropna are ignored.

        The differences between ``_positional_selector[]`` and :meth:`~GroupBy.nth`
        with ``as_index=False`` are:

        - Input to ``_positional_selector`` can include
          one or more slices whereas ``nth``
          just handles an integer or a list of integers.
        - ``_positional_selector`` can  accept a slice relative to the
          last row of each group.
        - ``_positional_selector`` does not have an equivalent to the
          ``nth()`` ``dropna`` parameter.

        Examples
        --------
        >>> df = pd.DataFrame([["a", 1], ["a", 2], ["a", 3], ["b", 4], ["b", 5]],
        ...                   columns=["A", "B"])
        >>> df.groupby("A")._positional_selector[1:2]
           A  B
        1  a  2
        4  b  5

        >>> df.groupby("A")._positional_selector[1, -1]
           A  B
        1  a  2
        2  a  3
        4  b  5
        )r   r   r   ÚGroupByr   ©ÚselfÚgroupby_self© r   úN/var/www/html/env/lib/python3.10/site-packages/pandas/core/groupby/indexing.pyÚ_positional_selector%   s
   Nþz)GroupByIndexingMixin._positional_selectorÚargúPositionalIndexer | tupleú
np.ndarrayc                 C  s¼   t |ƒr$tdd„ tt|ƒD ƒƒr|  ttt |ƒ¡}n+|  tt|ƒ¡}n"t|t	ƒr/|  
|¡}nt|ƒr<|  tt|ƒ¡}n
tdt|ƒ› d�ƒ‚t|tƒrX|rS| jdk}n| jdk }ttj|ƒS )Nc                 s  s   � | ]}t |ƒV  qd S ©N)r	   )Ú.0Úir   r   r   Ú	<genexpr>€   s   € zJGroupByIndexingMixin._make_mask_from_positional_indexer.<locals>.<genexpr>zInvalid index zE. Must be integer, list-like, slice or a tuple of integers and slicesr   )r
   Úallr   r   Ú_make_mask_from_listÚintÚ_make_mask_from_tupleÚtupleÚ
isinstanceÚsliceÚ_make_mask_from_slicer	   Ú_make_mask_from_intÚ	TypeErrorÚtypeÚboolÚ_ascending_countÚnpÚndarray©r   r   Úmaskr   r   r   Ú"_make_mask_from_positional_indexer{   s    
ÿ

z7GroupByIndexingMixin._make_mask_from_positional_indexerr"   c                 C  s"   |dkr	| j |kS | j| d kS )Nr   é   )r,   Ú_descending_count)r   r   r   r   r   r(   ˜   s   
z(GroupByIndexingMixin._make_mask_from_intÚargsúIterable[int]úbool | np.ndarrayc                 C  sP   dd„ |D ƒ}dd„ |D ƒ}d}|r|t  | j|¡O }|r&|t  | j|¡O }|S )Nc                 S  s   g | ]}|d kr|‘qS )r   r   ©r   r   r   r   r   Ú
<listcomp>Ÿ   s    z=GroupByIndexingMixin._make_mask_from_list.<locals>.<listcomp>c                 S  s   g | ]}|d k r| d ‘qS )r   r2   r   r7   r   r   r   r8       s    F)r-   Úisinr,   r3   )r   r4   ÚpositiveÚnegativer0   r   r   r   r!   ž   s   z)GroupByIndexingMixin._make_mask_from_listr$   c                 C  s\   d}|D ]'}t |ƒr||  tt|ƒ¡O }qt|tƒr"||  |¡O }qtdt|ƒ› d�ƒ‚|S )NFzInvalid argument z. Should be int or slice.)	r	   r(   r   r"   r%   r&   r'   Ú
ValueErrorr*   )r   r4   r0   r   r   r   r   r#   ¬   s   
ÿz*GroupByIndexingMixin._make_mask_from_tupler&   c                 C  s(  |j }|j}|j}|d ur|dk rtd|› d�ƒ‚d}|d u r!d}|d u r3|dkr2|| j| dkM }nF|dkrN|| j|kM }|dkrM|| j| | dkM }n+|| j| k M }| j| d }| j| j |d  dk }t || j|¡}||| dkM }|d ur’|dkrŠ|| j|k M }|S || j| kM }|S )Nr   zInvalid step z. Must be non-negativeTr2   )ÚstartÚstopÚstepr<   r,   r3   r-   Úwhere)r   r   r=   r>   r?   r0   Úoffset_arrayÚlimit_arrayr   r   r   r'   »   s<   €€þþz*GroupByIndexingMixin._make_mask_from_slicec                 C  s$   t rttj| ƒ}| ¡ S | }| ¡ S r   ©r   r   r   r   Ú_cumcount_arrayr   r   r   r   r,   å   s
   þz%GroupByIndexingMixin._ascending_countc                 C  s"   t r	ttj| ƒ}n| }|jdd�S )NF)Ú	ascendingrC   r   r   r   r   r3   î   s   z&GroupByIndexingMixin._descending_countN)r   r   )r   r   r   r   )r   r"   r   r   )r4   r5   r   r6   )r4   r$   r   r6   )r   r&   r   r6   )r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r1   r(   r!   r#   r'   r,   r3   r   r   r   r   r       s    
U



*r   c                   @  s    e Zd Zddd„Zdd
d„ZdS )r   Úgroupby_objectúgroupby.GroupByr   ÚNonec                 C  ó
   || _ d S r   ©rJ   ©r   rJ   r   r   r   Ú__init__ú   ó   
z"GroupByPositionalSelector.__init__r   r   úDataFrame | Seriesc                 C  s   | j  |¡}| j  |¡S )a  
        Select by positional index per group.

        Implements GroupBy._positional_selector

        Parameters
        ----------
        arg : PositionalIndexer | tuple
            Allowed values are:
            - int
            - int valued iterable such as list or range
            - slice with step either None or positive
            - tuple of integers and slices

        Returns
        -------
        Series
            The filtered subset of the original groupby Series.
        DataFrame
            The filtered subset of the original groupby DataFrame.

        See Also
        --------
        DataFrame.iloc : Integer-location based indexing for selection by position.
        GroupBy.head : Return first n rows of each group.
        GroupBy.tail : Return last n rows of each group.
        GroupBy._positional_selector : Return positional selection for each group.
        GroupBy.nth : Take the nth row from each group if n is an int, or a
            subset of rows, if n is a list of ints.
        )rJ   r1   Ú_mask_selected_objr/   r   r   r   Ú__getitem__ý   s   z%GroupByPositionalSelector.__getitem__N©rJ   rK   r   rL   )r   r   r   rR   )rF   rG   rH   rP   rT   r   r   r   r   r   ø   s    
r   c                   @  s2   e Zd ZdZddd„Z	dddd„Zddd„ZdS )ÚGroupByNthSelectorzO
    Dynamically substituted for GroupBy.nth to enable both call and index
    rJ   rK   r   rL   c                 C  rM   r   rN   rO   r   r   r   rP   %  rQ   zGroupByNthSelector.__init__NÚnr   ÚdropnaúLiteral['any', 'all', None]rR   c                 C  s   | j  ||¡S r   ©rJ   Ú_nth)r   rW   rX   r   r   r   Ú__call__(  s   zGroupByNthSelector.__call__c                 C  s   | j  |¡S r   rZ   )r   rW   r   r   r   rT   /  s   zGroupByNthSelector.__getitem__rU   r   )rW   r   rX   rY   r   rR   )rW   r   r   rR   )rF   rG   rH   rI   rP   r\   rT   r   r   r   r   rV      s    
ýrV   )Ú
__future__r   Úcollections.abcr   Útypingr   r   r   Únumpyr-   Úpandas.util._decoratorsr   r   Úpandas.core.dtypes.commonr	   r
   Úpandas._typingr   Úpandasr   r   Úpandas.core.groupbyr   r   r   r   rV   r   r   r   r   Ú<module>   s     Y'