o
    ¹­§iý°  ã                   @  s8  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 d dlmZ d dlmZ er€d dlZd d	l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 d dlmZ ej dkrhd dlm!Z! nd dl"m!Z! ej dkrzd dl#mZ nd dl"mZ G dd„ dƒZ$G dd„ dƒZ%G dd„ dƒZ&ddd„Z'dS ) é    )Úannotations)Úchain)ÚTYPE_CHECKINGÚAny)Ú	functions)Úparse_as_duration_string)Ú
deprecated)Ú_parse_inputs_as_iterableN)ÚCallableÚIterable)Ú	timedelta)Ú	DataFrame)ÚClosedIntervalÚIntoExprÚLabelÚQuantileMethodÚ
SchemaDictÚStartBy)ÚLazyGroupBy)é   é   )ÚSelf)r   é   c                   @  s   e Zd ZdZdNdd„ZdOdd„ZdPdd„ZdQdd„ZdRdd„ZdSdd„Z	dTd!d"„Z
dUdVd&d'„ZdUdVd(d)„ZdWd*d+„ZdXdYd/d0„Zed1ƒdWd2d3„ƒZd4d5œdZd7d8„Zd4d5œdZd9d:„ZdWd;d<„ZdWd=d>„ZdWd?d@„ZdWdAdB„ZdWdCdD„Z	Ed[d\dJdK„ZdWdLdM„Zd,S )]ÚGroupByzStarts a new GroupBy operation.Údfr   ÚbyúIntoExpr | Iterable[IntoExpr]Úmaintain_orderÚboolÚ
predicatesúIterable[Any] | NoneÚnamed_byr   ÚreturnÚNonec                O  s"   || _ || _|| _|| _|| _dS )a  
        Utility class for performing a group by operation over the given DataFrame.

        Generated by calling `df.group_by(...)`.

        Parameters
        ----------
        df
            DataFrame to perform the group by operation over.
        *by
            Column or columns to group by. Accepts expression input. Strings are parsed
            as column names.
        maintain_order
            Ensure that the order of the groups is consistent with the input data.
            This is slower than a default group by.
        predicates
            Predicate expressions to filter groups after aggregation.
        **named_by
            Additional column(s) to group by, specified as keyword arguments.
            The columns will be named as the keyword used.
        N)r   r   r!   r   r   )Úselfr   r   r   r   r!   © r%   úP/home/app/Keep/.python/lib/python3.10/site-packages/polars/dataframe/group_by.pyÚ__init__)   s
   
zGroupBy.__init__r   c                 C  s:   | j  ¡ j| ji | j¤d| ji¤Ž}| jr| | j¡S |S )Nr   )r   ÚlazyÚgroup_byr   r!   r   r   Úhaving)r$   r)   r%   r%   r&   Ú_lgbL   s   
ÿÿÿzGroupBy._lgbr   c                 C  s–   ddl m} | j ¡ | _d}| j ¡  d¡j| ji | j¤d| j	i¤Ž 
t ¡  |¡¡j| ¡ d}| t ¡  |¡¡ ¡ | _| |¡ ¡ | _d| _| S )u3  
        Allows iteration over the groups of the group by operation.

        Each group is represented by a tuple of `(name, data)`. The group names are
        tuples of the distinct group values that identify each group.

        Examples
        --------
        >>> df = pl.DataFrame({"foo": ["a", "a", "b"], "bar": [1, 2, 3]})
        >>> for name, data in df.group_by("foo"):  # doctest: +SKIP
        ...     print(name)
        ...     print(data)
        (a,)
        shape: (2, 2)
        â”Œâ”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”
        â”‚ foo â”† bar â”‚
        â”‚ --- â”† --- â”‚
        â”‚ str â”† i64 â”‚
        â•žâ•â•â•â•â•â•ªâ•â•â•â•â•â•¡
        â”‚ a   â”† 1   â”‚
        â”‚ a   â”† 2   â”‚
        â””â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”˜
        (b,)
        shape: (1, 2)
        â”Œâ”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”
        â”‚ foo â”† bar â”‚
        â”‚ --- â”† --- â”‚
        â”‚ str â”† i64 â”‚
        â•žâ•â•â•â•â•â•ªâ•â•â•â•â•â•¡
        â”‚ b   â”† 3   â”‚
        â””â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”˜
        r   ©ÚQueryOptFlagsÚ__POLARS_GB_GROUP_INDICESÚ__POLARS_GB_ROW_INDEXr   ©Zoptimizations)Úpolars.lazyframe.opt_flagsr-   r   Zrechunkr(   Úwith_row_indexr)   r   r!   r   ÚaggÚFÚfirstÚaliasÚcollectÚnoneÚselectÚallÚexcludeÚ	iter_rowsÚ_group_namesÚ	to_seriesÚ_group_indicesÚ_current_index©r$   r-   Ztemp_colZ	groups_dfr%   r%   r&   Ú__iter__T   s&   "þþþüÿzGroupBy.__iter__ú!tuple[tuple[Any, ...], DataFrame]c                 C  óN   | j t| jƒkr
t‚t| jƒ}| j| j| j  d d …f }|  j d7  _ ||fS ©Né   ©r@   Úlenr?   ÚStopIterationÚnextr=   r   ©r$   Ú
group_nameZ
group_datar%   r%   r&   Ú__next__ˆ   ó   
zGroupBy.__next__c                 G  s,   t | jg| j¢R | jt| j|ƒdœ| j¤ŽS )u(  
        Filter groups with a list of predicates after aggregation.

        Using this method is equivalent to adding the predicates to the aggregation and
        filtering afterwards.

        This method can be chained and all conditions will be combined using `&`.

        Parameters
        ----------
        *predicates
            Expressions that evaluate to a boolean value for each group. Typically, this
            requires the use of an aggregation function. Multiple predicates are
            combined using `&`.

        Examples
        --------
        Only keep groups that contain more than one element.

        >>> df = pl.DataFrame(
        ...     {
        ...         "a": ["a", "b", "a", "b", "c"],
        ...     }
        ... )
        >>> df.group_by("a").having(pl.len() > 1).agg()  # doctest: +IGNORE_RESULT
        shape: (2, 1)
        â”Œâ”€â”€â”€â”€â”€â”
        â”‚ a   â”‚
        â”‚ --- â”‚
        â”‚ str â”‚
        â•žâ•â•â•â•â•â•¡
        â”‚ b   â”‚
        â”‚ a   â”‚
        â””â”€â”€â”€â”€â”€â”˜
        )r   r   )r   r   r   r   Ú_chain_predicatesr   r!   ©r$   r   r%   r%   r&   r*   ’   s   $ÿþ
üûzGroupBy.havingÚaggsÚ
named_aggsc                 O  s,   ddl m} |  ¡ j|i |¤Žj| ¡ dS )u  
        Compute aggregations for each group of a group by operation.

        Parameters
        ----------
        *aggs
            Aggregations to compute for each group of the group by operation,
            specified as positional arguments.
            Accepts expression input. Strings are parsed as column names.
        **named_aggs
            Additional aggregations, specified as keyword arguments.
            The resulting columns will be renamed to the keyword used.

        Examples
        --------
        Compute the aggregation of the columns for each group.

        >>> df = pl.DataFrame(
        ...     {
        ...         "a": ["a", "b", "a", "b", "c"],
        ...         "b": [1, 2, 1, 3, 3],
        ...         "c": [5, 4, 3, 2, 1],
        ...     }
        ... )
        >>> df.group_by("a").agg(pl.col("b"), pl.col("c"))  # doctest: +IGNORE_RESULT
        shape: (3, 3)
        â”Œâ”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”
        â”‚ a   â”† b         â”† c         â”‚
        â”‚ --- â”† ---       â”† ---       â”‚
        â”‚ str â”† list[i64] â”† list[i64] â”‚
        â•žâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•â•â•â•â•¡
        â”‚ a   â”† [1, 1]    â”† [5, 3]    â”‚
        â”‚ b   â”† [2, 3]    â”† [4, 2]    â”‚
        â”‚ c   â”† [3]       â”† [1]       â”‚
        â””â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜

        Compute the sum of a column for each group.

        >>> df.group_by("a").agg(pl.col("b").sum())  # doctest: +IGNORE_RESULT
        shape: (3, 2)
        â”Œâ”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”
        â”‚ a   â”† b   â”‚
        â”‚ --- â”† --- â”‚
        â”‚ str â”† i64 â”‚
        â•žâ•â•â•â•â•â•ªâ•â•â•â•â•â•¡
        â”‚ a   â”† 2   â”‚
        â”‚ b   â”† 5   â”‚
        â”‚ c   â”† 3   â”‚
        â””â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”˜

        Compute multiple aggregates at once by passing a list of expressions.

        >>> df.group_by("a").agg([pl.sum("b"), pl.mean("c")])  # doctest: +IGNORE_RESULT
        shape: (3, 3)
        â”Œâ”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”
        â”‚ a   â”† b   â”† c   â”‚
        â”‚ --- â”† --- â”† --- â”‚
        â”‚ str â”† i64 â”† f64 â”‚
        â•žâ•â•â•â•â•â•ªâ•â•â•â•â•â•ªâ•â•â•â•â•â•¡
        â”‚ c   â”† 3   â”† 1.0 â”‚
        â”‚ a   â”† 2   â”† 4.0 â”‚
        â”‚ b   â”† 5   â”† 3.0 â”‚
        â””â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”˜

        Or use positional arguments to compute multiple aggregations in the same way.

        >>> df.group_by("a").agg(
        ...     pl.sum("b").name.suffix("_sum"),
        ...     (pl.col("c") ** 2).mean().name.suffix("_mean_squared"),
        ... )  # doctest: +IGNORE_RESULT
        shape: (3, 3)
        â”Œâ”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”
        â”‚ a   â”† b_sum â”† c_mean_squared â”‚
        â”‚ --- â”† ---   â”† ---            â”‚
        â”‚ str â”† i64   â”† f64            â”‚
        â•žâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•¡
        â”‚ a   â”† 2     â”† 17.0           â”‚
        â”‚ c   â”† 3     â”† 1.0            â”‚
        â”‚ b   â”† 5     â”† 10.0           â”‚
        â””â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜

        Use keyword arguments to easily name your expression inputs.

        >>> df.group_by("a").agg(
        ...     b_sum=pl.sum("b"),
        ...     c_mean_squared=(pl.col("c") ** 2).mean(),
        ... )  # doctest: +IGNORE_RESULT
        shape: (3, 3)
        â”Œâ”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”
        â”‚ a   â”† b_sum â”† c_mean_squared â”‚
        â”‚ --- â”† ---   â”† ---            â”‚
        â”‚ str â”† i64   â”† f64            â”‚
        â•žâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•¡
        â”‚ a   â”† 2     â”† 17.0           â”‚
        â”‚ c   â”† 3     â”† 1.0            â”‚
        â”‚ b   â”† 5     â”† 10.0           â”‚
        â””â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜
        r   r,   r0   )r1   r-   r+   r3   r7   r8   )r$   rQ   rR   r-   r%   r%   r&   r3   ¾   s   gÿÿþÿzGroupBy.aggÚfunctionú Callable[[DataFrame], DataFrame]c                 C  sh   | j r	d}t|ƒ‚| jrd}t|ƒ‚tdd„ | jD ƒƒs"d}t|ƒ‚| j}| jj | jj 	||| j
¡¡S )u1	  
        Apply a custom/user-defined function (UDF) over the groups as a sub-DataFrame.

        .. warning::
            This method is much slower than the native expressions API.
            Only use it if you cannot implement your logic otherwise.

        Implementing logic using a Python function is almost always *significantly*
        slower and more memory intensive than implementing the same logic using
        the native expression API because:

        - The native expression engine runs in Rust; UDFs run in Python.
        - Use of Python UDFs forces the DataFrame to be materialized in memory.
        - Polars-native expressions can be parallelised (UDFs cannot).
        - Polars-native expressions can be logically optimised (UDFs cannot).

        Wherever possible you should strongly prefer the native expression API
        to achieve the best performance.

        Parameters
        ----------
        function
            Custom function that receives a DataFrame and returns a DataFrame.

        Returns
        -------
        DataFrame

        Examples
        --------
        For each color group sample two rows:

        >>> df = pl.DataFrame(
        ...     {
        ...         "id": [0, 1, 2, 3, 4],
        ...         "color": ["red", "green", "green", "red", "red"],
        ...         "shape": ["square", "triangle", "square", "triangle", "square"],
        ...     }
        ... )
        >>> df.group_by("color").map_groups(
        ...     lambda group_df: group_df.sample(2)
        ... )  # doctest: +IGNORE_RESULT
        shape: (4, 3)
        â”Œâ”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”
        â”‚ id  â”† color â”† shape    â”‚
        â”‚ --- â”† ---   â”† ---      â”‚
        â”‚ i64 â”† str   â”† str      â”‚
        â•žâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•â•â•â•¡
        â”‚ 1   â”† green â”† triangle â”‚
        â”‚ 2   â”† green â”† square   â”‚
        â”‚ 4   â”† red   â”† square   â”‚
        â”‚ 3   â”† red   â”† triangle â”‚
        â””â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜

        It is better to implement this with an expression:

        >>> df.filter(
        ...     pl.int_range(pl.len()).shuffle().over("color") < 2
        ... )  # doctest: +IGNORE_RESULT
        ú<cannot call `map_groups` when filtering groups with `having`z;cannot call `map_groups` when grouping by named expressionsc                 s  s    | ]}t |tƒV  qd S ©N)Ú
isinstanceÚstr)Ú.0Úcr%   r%   r&   Ú	<genexpr>p  s   € z%GroupBy.map_groups.<locals>.<genexpr>z7cannot call `map_groups` when grouping by an expression)r   Ú	TypeErrorr!   r:   r   r   Ú	__class__Z
_from_pydfZ_dfZgroup_by_map_groupsr   )r$   rS   ÚmsgZby_strsr%   r%   r&   Ú
map_groups-  s   =ÿzGroupBy.map_groupsé   ÚnÚintc                 C  ó&   ddl m} |  ¡  |¡j| ¡ dS )un  
        Get the first `n` rows of each group.

        Parameters
        ----------
        n
            Number of rows to return.

        Examples
        --------
        >>> df = pl.DataFrame(
        ...     {
        ...         "letters": ["c", "c", "a", "c", "a", "b"],
        ...         "nrs": [1, 2, 3, 4, 5, 6],
        ...     }
        ... )
        >>> df
        shape: (6, 2)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”
        â”‚ letters â”† nrs â”‚
        â”‚ ---     â”† --- â”‚
        â”‚ str     â”† i64 â”‚
        â•žâ•â•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•¡
        â”‚ c       â”† 1   â”‚
        â”‚ c       â”† 2   â”‚
        â”‚ a       â”† 3   â”‚
        â”‚ c       â”† 4   â”‚
        â”‚ a       â”† 5   â”‚
        â”‚ b       â”† 6   â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”˜
        >>> df.group_by("letters").head(2).sort("letters")
        shape: (5, 2)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”
        â”‚ letters â”† nrs â”‚
        â”‚ ---     â”† --- â”‚
        â”‚ str     â”† i64 â”‚
        â•žâ•â•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•¡
        â”‚ a       â”† 3   â”‚
        â”‚ a       â”† 5   â”‚
        â”‚ b       â”† 6   â”‚
        â”‚ c       â”† 1   â”‚
        â”‚ c       â”† 2   â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”˜
        r   r,   r0   )r1   r-   r+   Úheadr7   Z_eager©r$   ra   r-   r%   r%   r&   rd   z  ó   -zGroupBy.headc                 C  rc   )um  
        Get the last `n` rows of each group.

        Parameters
        ----------
        n
            Number of rows to return.

        Examples
        --------
        >>> df = pl.DataFrame(
        ...     {
        ...         "letters": ["c", "c", "a", "c", "a", "b"],
        ...         "nrs": [1, 2, 3, 4, 5, 6],
        ...     }
        ... )
        >>> df
        shape: (6, 2)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”
        â”‚ letters â”† nrs â”‚
        â”‚ ---     â”† --- â”‚
        â”‚ str     â”† i64 â”‚
        â•žâ•â•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•¡
        â”‚ c       â”† 1   â”‚
        â”‚ c       â”† 2   â”‚
        â”‚ a       â”† 3   â”‚
        â”‚ c       â”† 4   â”‚
        â”‚ a       â”† 5   â”‚
        â”‚ b       â”† 6   â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”˜
        >>> df.group_by("letters").tail(2).sort("letters")
        shape: (5, 2)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”
        â”‚ letters â”† nrs â”‚
        â”‚ ---     â”† --- â”‚
        â”‚ str     â”† i64 â”‚
        â•žâ•â•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•¡
        â”‚ a       â”† 3   â”‚
        â”‚ a       â”† 5   â”‚
        â”‚ b       â”† 6   â”‚
        â”‚ c       â”† 2   â”‚
        â”‚ c       â”† 4   â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”˜
        r   r,   r0   )r1   r-   r+   Útailr7   r8   re   r%   r%   r&   rg   «  rf   zGroupBy.tailc                 C  s   |   t ¡ ¡S )uj  
        Aggregate the groups into Series.

        Examples
        --------
        >>> df = pl.DataFrame({"a": ["one", "two", "one", "two"], "b": [1, 2, 3, 4]})
        >>> df.group_by("a", maintain_order=True).all()
        shape: (2, 2)
        â”Œâ”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”
        â”‚ a   â”† b         â”‚
        â”‚ --- â”† ---       â”‚
        â”‚ str â”† list[i64] â”‚
        â•žâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•â•â•â•â•¡
        â”‚ one â”† [1, 3]    â”‚
        â”‚ two â”† [2, 4]    â”‚
        â””â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜
        )r3   r4   r:   ©r$   r%   r%   r&   r:   Ü  s   zGroupBy.allNÚnameú
str | Nonec                 C  s$   t  ¡ }|dur| |¡}|  |¡S )us  
        Return the number of rows in each group.

        Parameters
        ----------
        name
            Assign a name to the resulting column; if unset, defaults to "len".

        Examples
        --------
        >>> df = pl.DataFrame({"a": ["Apple", "Apple", "Orange"], "b": [1, None, 2]})
        >>> df.group_by("a").len()  # doctest: +IGNORE_RESULT
        shape: (2, 2)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”
        â”‚ a      â”† len â”‚
        â”‚ ---    â”† --- â”‚
        â”‚ str    â”† u32 â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•¡
        â”‚ Apple  â”† 2   â”‚
        â”‚ Orange â”† 1   â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”˜
        >>> df.group_by("a").len(name="n")  # doctest: +IGNORE_RESULT
        shape: (2, 2)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”
        â”‚ a      â”† n   â”‚
        â”‚ ---    â”† --- â”‚
        â”‚ str    â”† u32 â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•¡
        â”‚ Apple  â”† 2   â”‚
        â”‚ Orange â”† 1   â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”˜
        N)r4   rH   r6   r3   )r$   ri   Zlen_exprr%   r%   r&   rH   ð  s   !

zGroupBy.lenz6`GroupBy.count` was renamed; use `GroupBy.len` insteadc                 C  s   |   t ¡  d¡¡S )uZ  
        Return the number of rows in each group.

        .. deprecated:: 0.20.5
            This method has been renamed to :func:`GroupBy.len`.

        Rows containing null values count towards the total.

        Examples
        --------
        >>> df = pl.DataFrame(
        ...     {
        ...         "a": ["Apple", "Apple", "Orange"],
        ...         "b": [1, None, 2],
        ...     }
        ... )
        >>> df.group_by("a").count()  # doctest: +SKIP
        shape: (2, 2)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”
        â”‚ a      â”† count â”‚
        â”‚ ---    â”† ---   â”‚
        â”‚ str    â”† u32   â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•¡
        â”‚ Apple  â”† 2     â”‚
        â”‚ Orange â”† 1     â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”˜
        Úcount)r3   r4   rH   r6   rh   r%   r%   r&   rk     s   zGroupBy.countF©Úignore_nullsrm   c                C  ó   |   t ¡ j|d¡S )u  
        Aggregate the first values in the group.

        Parameters
        ----------
        ignore_nulls
            Ignore null values (default `False`).
            If set to `True`, the first non-null value for each aggregation is returned,
            otherwise `None` is returned if no non-null value exists.

        Examples
        --------
        >>> df = pl.DataFrame(
        ...     {
        ...         "a": [1, 2, 2, 3, 4, 5],
        ...         "b": [0.5, 0.5, 4, 10, 13, 14],
        ...         "c": [None, True, True, False, False, True],
        ...         "d": ["Apple", "Orange", "Apple", "Apple", "Banana", "Banana"],
        ...     }
        ... )
        >>> df.group_by("d", maintain_order=True).first()
        shape: (3, 4)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”
        â”‚ d      â”† a   â”† b    â”† c     â”‚
        â”‚ ---    â”† --- â”† ---  â”† ---   â”‚
        â”‚ str    â”† i64 â”† f64  â”† bool  â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•¡
        â”‚ Apple  â”† 1   â”† 0.5  â”† null  â”‚
        â”‚ Orange â”† 2   â”† 0.5  â”† true  â”‚
        â”‚ Banana â”† 4   â”† 13.0 â”† false â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”˜
        >>> df.group_by("d", maintain_order=True).first(ignore_nulls=True)
        shape: (3, 4)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”
        â”‚ d      â”† a   â”† b    â”† c     â”‚
        â”‚ ---    â”† --- â”† ---  â”† ---   â”‚
        â”‚ str    â”† i64 â”† f64  â”† bool  â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•¡
        â”‚ Apple  â”† 1   â”† 0.5  â”† true  â”‚
        â”‚ Orange â”† 2   â”† 0.5  â”† true  â”‚
        â”‚ Banana â”† 4   â”† 13.0 â”† false â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”˜
        rl   )r3   r4   r:   r5   ©r$   rm   r%   r%   r&   r5   5  ó   ,zGroupBy.firstc                C  rn   )uø  
        Aggregate the last values in the group.

        Parameters
        ----------
        ignore_nulls
            Ignore null values (default `False`).
            If set to `True`, the last non-null value for each column is returned,
            otherwise `None` is returned if no non-null value exists.

        Examples
        --------
        >>> df = pl.DataFrame(
        ...     {
        ...         "a": [1, 2, 2, 3, 4, 5],
        ...         "b": [0.5, 0.5, 4, 10, 14, None],
        ...         "c": [True, True, True, None, False, True],
        ...         "d": ["Apple", "Orange", "Apple", "Apple", "Banana", "Banana"],
        ...     }
        ... )
        >>> df.group_by("d", maintain_order=True).last()
        shape: (3, 4)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”
        â”‚ d      â”† a   â”† b    â”† c    â”‚
        â”‚ ---    â”† --- â”† ---  â”† ---  â”‚
        â”‚ str    â”† i64 â”† f64  â”† bool â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•ªâ•â•â•â•â•â•â•¡
        â”‚ Apple  â”† 3   â”† 10.0 â”† null â”‚
        â”‚ Orange â”† 2   â”† 0.5  â”† true â”‚
        â”‚ Banana â”† 5   â”† null â”† true â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”˜
        >>> df.group_by("d", maintain_order=True).last(ignore_nulls=True)
        shape: (3, 4)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”
        â”‚ d      â”† a   â”† b    â”† c    â”‚
        â”‚ ---    â”† --- â”† ---  â”† ---  â”‚
        â”‚ str    â”† i64 â”† f64  â”† bool â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•ªâ•â•â•â•â•â•â•¡
        â”‚ Apple  â”† 3   â”† 10.0 â”† true â”‚
        â”‚ Orange â”† 2   â”† 0.5  â”† true â”‚
        â”‚ Banana â”† 5   â”† 14.0 â”† true â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”˜
        rl   )r3   r4   r:   Úlastro   r%   r%   r&   rq   c  rp   zGroupBy.lastc                 C  ó   |   t ¡  ¡ ¡S )u@  
        Reduce the groups to the maximal value.

        Examples
        --------
        >>> df = pl.DataFrame(
        ...     {
        ...         "a": [1, 2, 2, 3, 4, 5],
        ...         "b": [0.5, 0.5, 4, 10, 13, 14],
        ...         "c": [True, True, True, False, False, True],
        ...         "d": ["Apple", "Orange", "Apple", "Apple", "Banana", "Banana"],
        ...     }
        ... )
        >>> df.group_by("d", maintain_order=True).max()
        shape: (3, 4)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”
        â”‚ d      â”† a   â”† b    â”† c    â”‚
        â”‚ ---    â”† --- â”† ---  â”† ---  â”‚
        â”‚ str    â”† i64 â”† f64  â”† bool â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•ªâ•â•â•â•â•â•â•¡
        â”‚ Apple  â”† 3   â”† 10.0 â”† true â”‚
        â”‚ Orange â”† 2   â”† 0.5  â”† true â”‚
        â”‚ Banana â”† 5   â”† 14.0 â”† true â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”˜
        )r3   r4   r:   Úmaxrh   r%   r%   r&   rs   ‘  ó   zGroupBy.maxc                 C  rr   )u·  
        Reduce the groups to the mean values.

        Examples
        --------
        >>> df = pl.DataFrame(
        ...     {
        ...         "a": [1, 2, 2, 3, 4, 5],
        ...         "b": [0.5, 0.5, 4, 10, 13, 14],
        ...         "c": [True, True, True, False, False, True],
        ...         "d": ["Apple", "Orange", "Apple", "Apple", "Banana", "Banana"],
        ...     }
        ... )
        >>> df.group_by("d", maintain_order=True).mean()
        shape: (3, 4)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”
        â”‚ d      â”† a   â”† b        â”† c        â”‚
        â”‚ ---    â”† --- â”† ---      â”† ---      â”‚
        â”‚ str    â”† f64 â”† f64      â”† f64      â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•â•â•â•¡
        â”‚ Apple  â”† 2.0 â”† 4.833333 â”† 0.666667 â”‚
        â”‚ Orange â”† 2.0 â”† 0.5      â”† 1.0      â”‚
        â”‚ Banana â”† 4.5 â”† 13.5     â”† 0.5      â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜
        )r3   r4   r:   Úmeanrh   r%   r%   r&   ru   ­  rt   zGroupBy.meanc                 C  rr   )uZ  
        Return the median per group.

        Examples
        --------
        >>> df = pl.DataFrame(
        ...     {
        ...         "a": [1, 2, 2, 3, 4, 5],
        ...         "b": [0.5, 0.5, 4, 10, 13, 14],
        ...         "d": ["Apple", "Banana", "Apple", "Apple", "Banana", "Banana"],
        ...     }
        ... )
        >>> df.group_by("d", maintain_order=True).median()
        shape: (2, 3)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”
        â”‚ d      â”† a   â”† b    â”‚
        â”‚ ---    â”† --- â”† ---  â”‚
        â”‚ str    â”† f64 â”† f64  â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•¡
        â”‚ Apple  â”† 2.0 â”† 4.0  â”‚
        â”‚ Banana â”† 4.0 â”† 13.0 â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”˜
        )r3   r4   r:   Úmedianrh   r%   r%   r&   rv   É  ó   zGroupBy.medianc                 C  rr   )uO  
        Reduce the groups to the minimal value.

        Examples
        --------
        >>> df = pl.DataFrame(
        ...     {
        ...         "a": [1, 2, 2, 3, 4, 5],
        ...         "b": [0.5, 0.5, 4, 10, 13, 14],
        ...         "c": [True, True, True, False, False, True],
        ...         "d": ["Apple", "Orange", "Apple", "Apple", "Banana", "Banana"],
        ...     }
        ... )
        >>> df.group_by("d", maintain_order=True).min()
        shape: (3, 4)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”€â”
        â”‚ d      â”† a   â”† b    â”† c     â”‚
        â”‚ ---    â”† --- â”† ---  â”† ---   â”‚
        â”‚ str    â”† i64 â”† f64  â”† bool  â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•ªâ•â•â•â•â•â•â•â•¡
        â”‚ Apple  â”† 1   â”† 0.5  â”† false â”‚
        â”‚ Orange â”† 2   â”† 0.5  â”† true  â”‚
        â”‚ Banana â”† 4   â”† 13.0 â”† false â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”€â”˜
        )r3   r4   r:   Úminrh   r%   r%   r&   rx   ã  rt   zGroupBy.minc                 C  rr   )uV  
        Count the unique values per group.

        Examples
        --------
        >>> df = pl.DataFrame(
        ...     {
        ...         "a": [1, 2, 1, 3, 4, 5],
        ...         "b": [0.5, 0.5, 0.5, 10, 13, 14],
        ...         "d": ["Apple", "Banana", "Apple", "Apple", "Banana", "Banana"],
        ...     }
        ... )
        >>> df.group_by("d", maintain_order=True).n_unique()
        shape: (2, 3)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”
        â”‚ d      â”† a   â”† b   â”‚
        â”‚ ---    â”† --- â”† --- â”‚
        â”‚ str    â”† u32 â”† u32 â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•ªâ•â•â•â•â•â•¡
        â”‚ Apple  â”† 2   â”† 2   â”‚
        â”‚ Banana â”† 3   â”† 3   â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”˜
        )r3   r4   r:   Ún_uniquerh   r%   r%   r&   ry   ÿ  rw   zGroupBy.n_uniqueÚnearestÚquantileÚfloatÚinterpolationr   c                 C  s   |   t ¡ j||d¡S )ui  
        Compute the quantile per group.

        Parameters
        ----------
        quantile
            Quantile between 0.0 and 1.0.
        interpolation : {'nearest', 'higher', 'lower', 'midpoint', 'linear', 'equiprobable'}
            Interpolation method.

        Examples
        --------
        >>> df = pl.DataFrame(
        ...     {
        ...         "a": [1, 2, 2, 3, 4, 5],
        ...         "b": [0.5, 0.5, 4, 10, 13, 14],
        ...         "d": ["Apple", "Orange", "Apple", "Apple", "Banana", "Banana"],
        ...     }
        ... )
        >>> df.group_by("d", maintain_order=True).quantile(1)
        shape: (3, 3)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”
        â”‚ d      â”† a   â”† b    â”‚
        â”‚ ---    â”† --- â”† ---  â”‚
        â”‚ str    â”† f64 â”† f64  â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•¡
        â”‚ Apple  â”† 3.0 â”† 10.0 â”‚
        â”‚ Orange â”† 2.0 â”† 0.5  â”‚
        â”‚ Banana â”† 5.0 â”† 14.0 â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”˜
        )r}   )r3   r4   r:   r{   )r$   r{   r}   r%   r%   r&   r{     s   "zGroupBy.quantilec                 C  rr   )u'  
        Reduce the groups to the sum.

        Examples
        --------
        >>> df = pl.DataFrame(
        ...     {
        ...         "a": [1, 2, 2, 3, 4, 5],
        ...         "b": [0.5, 0.5, 4, 10, 13, 14],
        ...         "c": [True, True, True, False, False, True],
        ...         "d": ["Apple", "Orange", "Apple", "Apple", "Banana", "Banana"],
        ...     }
        ... )
        >>> df.group_by("d", maintain_order=True).sum()
        shape: (3, 4)
        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”€â”¬â”€â”€â”€â”€â”€â”
        â”‚ d      â”† a   â”† b    â”† c   â”‚
        â”‚ ---    â”† --- â”† ---  â”† --- â”‚
        â”‚ str    â”† i64 â”† f64  â”† u32 â”‚
        â•žâ•â•â•â•â•â•â•â•â•ªâ•â•â•â•â•â•ªâ•â•â•â•â•â•â•ªâ•â•â•â•â•â•¡
        â”‚ Apple  â”† 6   â”† 14.5 â”† 2   â”‚
        â”‚ Orange â”† 2   â”† 0.5  â”† 1   â”‚
        â”‚ Banana â”† 9   â”† 27.0 â”† 1   â”‚
        â””â”€â”€â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”€â”´â”€â”€â”€â”€â”€â”˜
        )r3   r4   r:   Úsumrh   r%   r%   r&   r~   =  rt   zGroupBy.sum)r   r   r   r   r   r   r   r    r!   r   r"   r#   )r"   r   ©r"   r   )r"   rC   )r   r   r"   r   ©rQ   r   rR   r   r"   r   )rS   rT   r"   r   )r`   )ra   rb   r"   r   )r"   r   rV   )ri   rj   r"   r   )rm   r   r"   r   )rz   )r{   r|   r}   r   r"   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r'   r+   rB   rM   r*   r3   r_   rd   rg   r:   rH   r   rk   r5   rq   rs   ru   rv   rx   ry   r{   r~   r%   r%   r%   r&   r   &   s2    

#

4


,
oM1
1&.
.



ÿ$r   c                   @  sL   e Zd ZdZd(dd„Zd)dd„Zd*dd„Zd+dd„Zd,dd „Zd-d%d&„Z	d'S ).ÚRollingGroupByz‰
    A rolling grouper.

    This has an `.agg` method which will allow you to run all polars expressions in a
    group by context.
    r   r   Úindex_columnr   Úperiodústr | timedeltaÚoffsetústr | timedelta | NoneÚclosedr   r)   ú$IntoExpr | Iterable[IntoExpr] | Noner   r    r"   r#   c                C  s>   t |ƒ}t |ƒ}|| _|| _|| _|| _|| _|| _|| _d S rV   )r   r   Útime_columnr‡   r‰   r‹   r)   r   )r$   r   r†   r‡   r‰   r‹   r)   r   r%   r%   r&   r'   b  s   
zRollingGroupBy.__init__r   c                 C  sŠ   ddl m} d}| j ¡  d¡j| j| j| j| j	| j
d t ¡  |¡¡j| ¡ d}| t ¡  |¡¡ ¡ | _| |¡ ¡ | _d| _| S )Nr   r,   r.   r/   ©r†   r‡   r‰   r‹   r)   r0   )r1   r-   r   r(   r2   Úrollingr   r‡   r‰   r‹   r)   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   r%   r%   r&   rB   x  s&   ù	öÿzRollingGroupBy.__iter__ú$tuple[tuple[object, ...], DataFrame]c                 C  rD   rE   rG   rK   r%   r%   r&   rM     rN   zRollingGroupBy.__next__r   c              
   G  s*   t | j| j| j| j| j| jt| j|ƒdS )á  
        Filter groups with a list of predicates after aggregation.

        Using this method is equivalent to adding the predicates to the aggregation and
        filtering afterwards.

        This method can be chained and all conditions will be combined using `&`.

        Parameters
        ----------
        *predicates
            Expressions that evaluate to a boolean value for each group. Typically, this
            requires the use of an aggregation function. Multiple predicates are
            combined using `&`.
        )r‡   r‰   r‹   r)   r   )	r…   r   r   r‡   r‰   r‹   r)   rO   r   rP   r%   r%   r&   r*   š  s   
ùzRollingGroupBy.havingrQ   rR   c                 O  s^   ddl m} | j ¡ j| j| j| j| j| j	d}| j
r!| | j
¡}|j|i |¤Žj| ¡ dS )áë  
        Compute aggregations for each group of a group by operation.

        Parameters
        ----------
        *aggs
            Aggregations to compute for each group of the group by operation,
            specified as positional arguments.
            Accepts expression input. Strings are parsed as column names.
        **named_aggs
            Additional aggregations, specified as keyword arguments.
            The resulting columns will be renamed to the keyword used.
        r   r,   rŽ   r0   )r1   r-   r   r(   r   r   r‡   r‰   r‹   r)   r   r*   r3   r7   r8   ©r$   rQ   rR   r-   r)   r%   r%   r&   r3   ´  s   
ûÿzRollingGroupBy.aggrS   rT   ÚschemaúSchemaDict | Nonec                 C  sV   ddl m} | jrd}t|ƒ‚| j ¡ j| j| j| j	| j
| jd ||¡j| ¡ dS )áö  
        Apply a custom/user-defined function (UDF) over the groups as a new DataFrame.

        Using this is considered an anti-pattern as it will be very slow because:

        - it forces the engine to materialize the whole `DataFrames` for the groups.
        - it is not parallelized.
        - it blocks optimizations as the passed python function is opaque to the
          optimizer.

        The idiomatic way to apply custom functions over multiple columns is using:

        `pl.struct([my_columns]).map_elements(lambda struct_series: ..)`

        Parameters
        ----------
        function
            Function to apply over each group of the `LazyFrame`; it receives
            a DataFrame and should return a DataFrame.
        schema
            Schema of the output function. This has to be known statically. If the
            given schema is incorrect, this is a bug in the caller's query and may
            lead to errors. If set to None, polars assumes the schema is unchanged.
        r   r,   rU   rŽ   r0   )r1   r-   r   r\   r   r(   r   r   r‡   r‰   r‹   r)   r_   r7   r8   ©r$   rS   r”   r-   r^   r%   r%   r&   r_   Ö  s    ú÷ÿzRollingGroupBy.map_groupsN)r   r   r†   r   r‡   rˆ   r‰   rŠ   r‹   r   r)   rŒ   r   r    r"   r#   r   ©r"   r   )r   r   r"   r…   r€   ©rS   rT   r”   r•   r"   r   ©
r   r‚   rƒ   r„   r'   rB   rM   r*   r3   r_   r%   r%   r%   r&   r…   Z  s    





"r…   c                   @  sL   e Zd ZdZd/dd„Zd0dd„Zd1dd „Zd2d"d#„Zd3d&d'„Zd4d,d-„Z	d.S )5ÚDynamicGroupByz…
    A dynamic grouper.

    This has an `.agg` method which allows you to run all polars expressions in a
    group by context.
    r   r   r†   r   Úeveryrˆ   r‡   rŠ   r‰   Úinclude_boundariesr   r‹   r   Úlabelr   r)   rŒ   Ústart_byr   r   r    r"   r#   c       	         C  s^   t |ƒ}t |ƒ}t |ƒ}|| _|| _|| _|| _|| _|| _|| _|| _|	| _	|
| _
|| _d S rV   )r   r   r   rœ   r‡   r‰   rž   r   r‹   r)   rŸ   r   )r$   r   r†   rœ   r‡   r‰   r   r‹   rž   r)   rŸ   r   r%   r%   r&   r'     s   
zDynamicGroupBy.__init__r   c                 C  sš   ddl m} d}| j ¡  d¡j| j| j| j| j	| j
| j| j| j| jd	 t ¡  |¡¡j| ¡ d}| t ¡  |¡¡ ¡ | _| |¡ ¡ | _d| _| S )Nr   r,   r.   r/   ©	r†   rœ   r‡   r‰   rž   r   r‹   r)   rŸ   r0   )r1   r-   r   r(   r2   Úgroup_by_dynamicr   rœ   r‡   r‰   rž   r   r‹   r)   rŸ   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   r%   r%   r&   rB   .  s.   õòÿzDynamicGroupBy.__iter__r   c                 C  rD   rE   rG   rK   r%   r%   r&   rM   J  rN   zDynamicGroupBy.__next__r   c                 G  s:   t | j| j| j| j| j| j| j| j| j	| j
t| j|ƒdS )r‘   )	rœ   r‡   r‰   r   r‹   rž   r)   rŸ   r   )r›   r   r   rœ   r‡   r‰   r   r‹   rž   r)   rŸ   rO   r   rP   r%   r%   r&   r*   T  s   
õzDynamicGroupBy.havingrQ   rR   c                 O  sn   ddl m} | j ¡ j| j| j| j| j| j	| j
| j| j| jd	}| jr)| | j¡}|j|i |¤Žj| ¡ dS )r’   r   r,   r    r0   )r1   r-   r   r(   r¡   r   rœ   r‡   r‰   rž   r   r‹   r)   rŸ   r   r*   r3   r7   r8   r“   r%   r%   r&   r3   r  s"   
÷ÿzDynamicGroupBy.aggrS   rT   r”   r•   c              
   C  sb   ddl m} | jrd}t|ƒ‚| j ¡ j| j| j| j	| j
| j| j| j| jd ||¡j| ¡ dS )r–   r   r,   rU   )r†   rœ   r‡   r‰   r   r‹   r)   rŸ   r0   )r1   r-   r   r\   r   r(   r¡   r   rœ   r‡   r‰   r   r‹   r)   rŸ   r_   r7   r8   r—   r%   r%   r&   r_   ˜  s&   ÷ôÿzDynamicGroupBy.map_groupsN)r   r   r†   r   rœ   rˆ   r‡   rŠ   r‰   rŠ   r   r   r‹   r   rž   r   r)   rŒ   rŸ   r   r   r    r"   r#   r   r˜   )r   r   r"   r›   r€   r™   rš   r%   r%   r%   r&   r›     s    





&r›   ÚlhsúIterable[IntoExpr] | NoneÚrhsú)tuple[IntoExpr | Iterable[IntoExpr], ...]r"   úIterable[Any]c                 C  s   | d urt | t|ƒƒS t|ƒS rV   )r   r	   )r¢   r¤   r%   r%   r&   rO   Ì  s
   ÿÿýrO   )r¢   r£   r¤   r¥   r"   r¦   )(Ú
__future__r   Ú	itertoolsr   Útypingr   r   Zpolarsr   r4   Zpolars._utils.convertr   Zpolars._utils.deprecationr   Zpolars._utils.parse.exprr	   ÚsysÚcollections.abcr
   r   Údatetimer   r   Zpolars._typingr   r   r   r   r   r   Zpolars.lazyframe.group_byr   Úversion_infor   Ztyping_extensionsÚwarningsr   r…   r›   rO   r%   r%   r%   r&   Ú<module>   s@     

      : . F