U
    +if%                     @  s   d dl mZ d dlmZmZmZmZ d dlZd dl	m
Z
 d dlmZmZ d dlmZmZ erxd 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)TYPE_CHECKINGIterableLiteralcastN)PositionalIndexer)cache_readonlydoc)
is_integeris_list_like)	DataFrameSeries)groupbyc                   @  s   e Zd ZdZeddddZdddd	d
ZdddddZdddddZdddddZ	dddddZ
eddddZeddddZdS )GroupByIndexingMixinz<
    Mixin for adding ._positional_selector to GroupBy.
    GroupByPositionalSelector)returnc                 C  s   t rttj| }n| }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   selfZgroupby_self r   O/home/mars/bis/venv/lib/python3.8/site-packages/pandas/core/groupby/indexing.py_positional_selector$   s    Nz)GroupByIndexingMixin._positional_selectorPositionalIndexer | tuplez
np.ndarrayargr   c                 C  s   t |rHtdd tt|D r6| ttt |}q| tt|}nDt|t	r^| 
|}n.t|rx| tt|}ntdt| dt|tr|r| 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npZndarrayr   r   maskr   r   r   "_make_mask_from_positional_indexery   s     


z7GroupByIndexingMixin._make_mask_from_positional_indexerr!   c                 C  s&   |dkr| j |kS | j| d kS d S )Nr      )r+   _descending_count)r   r   r   r   r   r'      s    
z(GroupByIndexingMixin._make_mask_from_intzIterable[int]zbool | np.ndarray)argsr   c                 C  sP   dd |D }dd |D }d}|r6|t | j|O }|rL|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   r0   r   r3   r   r   r   r4      s      F)r,   isinr+   r1   )r   r2   Zpositivenegativer.   r   r   r   r       s    z)GroupByIndexingMixin._make_mask_from_listr#   c                 C  s^   d}|D ]P}t |r*|| tt|O }qt|trD|| |O }qtdt| dq|S )NFzInvalid argument z. Should be int or slice.)	r
   r'   r   r!   r$   r%   r&   
ValueErrorr)   )r   r2   r.   r   r   r   r   r"      s    
z*GroupByIndexingMixin._make_mask_from_tupler%   c                 C  s*  |j }|j}|j}|d k	r2|dk r2td| dd}|d krBd}|d krf|dkr|| j| dkM }n|dkr|| j|kM }|dkr|| j| | dkM }nV|| j| k M }| j| d }| j| j |d  dk }t|| j|}||| dkM }|d k	r&|dkr|| j|k M }n|| j| kM }|S )Nr   zInvalid step z. Must be non-negativeTr0   )startstopstepr7   r+   r1   r,   where)r   r   r8   r9   r:   r.   Zoffset_arrayZlimit_arrayr   r   r   r&      s6    

z*GroupByIndexingMixin._make_mask_from_slicec                 C  s   t rttj| }n| }| S r   r   r   r   r   Z_cumcount_arrayr   r   r   r   r+      s    z%GroupByIndexingMixin._ascending_countc                 C  s"   t rttj| }n| }|jddS )NF)Z	ascendingr<   r   r   r   r   r1      s    z&GroupByIndexingMixin._descending_countN)__name__
__module____qualname____doc__r   r   r/   r'   r    r"   r&   r+   r1   r   r   r   r   r      s   T*r   c                   @  s*   e Zd ZddddZddddd	Zd
S )r   groupby.GroupBygroupby_objectc                 C  s
   || _ d S r   rB   r   rC   r   r   r   __init__   s    z"GroupByPositionalSelector.__init__r   DataFrame | Seriesr   c                 C  s"   | j   | 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.
        )rC   Z_reset_group_selectionr/   Z_mask_selected_objr-   r   r   r   __getitem__   s    
z%GroupByPositionalSelector.__getitem__N)r=   r>   r?   rE   rG   r   r   r   r   r      s   r   c                   @  sB   e Zd ZdZddddZdddd	d
ddZdd	dddZdS )GroupByNthSelectorzO
    Dynamically substituted for GroupBy.nth to enable both call and index
    rA   rB   c                 C  s
   || _ d S r   rB   rD   r   r   r   rE   $  s    zGroupByNthSelector.__init__Nr   zLiteral[('any', 'all', None)]rF   )ndropnar   c                 C  s   | j ||S r   rC   Z
nth_actual)r   rI   rJ   r   r   r   __call__'  s    zGroupByNthSelector.__call__)rI   r   c                 C  s   | j |S r   rK   )r   rI   r   r   r   rG   .  s    zGroupByNthSelector.__getitem__)N)r=   r>   r?   r@   rE   rL   rG   r   r   r   r   rH     s
    rH   )
__future__r   typingr   r   r   r   numpyr,   Zpandas._typingr   Zpandas.util._decoratorsr   r	   Zpandas.core.dtypes.commonr
   r   Zpandasr   r   Zpandas.core.groupbyr   r   r   r   rH   r   r   r   r   <module>   s    X(