§
    q-PhR5  γ                  σΒ    d dl mZ d dlZd dlmZmZ d dlmZ d dl	m
Z
  ej        e¦  «        5  d dlmZ ddd¦  «         n# 1 swxY w Y   erd dlmZ d dlmZ ddZdS )ι    )ΪannotationsN)ΪTYPE_CHECKINGΪAny)Ϊ,parse_predicates_constraints_into_expression)ΪIterable)ΪIntoExprColumnΪ
predicatesϊ0IntoExprColumn | Iterable[IntoExprColumn] | boolΪconstraintsr   Ϊreturnϊpl.Whenc                 σf    t          | i |€}t          j        t          j        |¦  «        ¦  «        S )u2  
    Start a `when-then-otherwise` expression.

    Always initiated by a `pl.when().then()`., and optionally followed by chaining one
    or more `.when().then()` statements.

    An optional `.otherwise()` can be appended at the end. If not declared, a default
    of `.otherwise(None)` is used.

    Similar to :func:`coalesce`, the value from the first condition that
    evaluates to True will be picked.

    If all conditions are False, the `otherwise` value is picked.

    Parameters
    ----------
    predicates
        Condition(s) that must be met in order to apply the subsequent statement.
        Accepts one or more boolean expressions, which are implicitly combined with
        `&`.
    constraints
        Apply conditions as `col_name = value` keyword arguments that are treated as
        equality matches, such as `x = 123`. As with the predicates parameter, multiple
        conditions are implicitly combined using `&`.

    Warnings
    --------
    Polars computes all expressions passed to `when-then-otherwise` in parallel and
    filters afterwards. This means each expression must be valid on its own, regardless
    of the conditions in the `when-then-otherwise` chain.

    Notes
    -----
    String inputs e.g. `when("string")`, `then("string")` or `otherwise("string")`
    are parsed as column names. :func:`lit` can be used to create string values.

    Examples
    --------
    Below we add a column with the value 1, where column "foo" > 2 and the value
    1 + column "bar" where it isn't.

    >>> df = pl.DataFrame({"foo": [1, 3, 4], "bar": [3, 4, 0]})
    >>> df.with_columns(
    ...     pl.when(pl.col.foo > 2).then(1).otherwise(1 + pl.col.bar).alias("val")
    ... )
    shape: (3, 3)
    βββββββ¬ββββββ¬ββββββ
    β foo β bar β val β
    β --- β --- β --- β
    β i64 β i64 β i64 β
    βββββββͺββββββͺββββββ‘
    β 1   β 3   β 4   β
    β 3   β 4   β 1   β
    β 4   β 0   β 1   β
    βββββββ΄ββββββ΄ββββββ

    Note that `when-then` always executes all expressions.

    The results are folded left to right, picking the `then` value from the first `when`
    condition that is True.

    If no `when` condition is True the `otherwise` value is picked.

    >>> df.with_columns(
    ...     when = pl.col.foo > 2,
    ...     then = 1,
    ...     otherwise = 1 + pl.col.bar
    ... ).with_columns(
    ...     pl.when("when").then("then").otherwise("otherwise").alias("val")
    ... )
    shape: (3, 6)
    βββββββ¬ββββββ¬ββββββββ¬βββββββ¬ββββββββββββ¬ββββββ
    β foo β bar β when  β then β otherwise β val β
    β --- β --- β ---   β ---  β ---       β --- β
    β i64 β i64 β bool  β i32  β i64       β i64 β
    βββββββͺββββββͺββββββββͺβββββββͺββββββββββββͺββββββ‘
    β 1   β 3   β false β 1    β 4         β 4   β
    β 3   β 4   β true  β 1    β 5         β 1   β
    β 4   β 0   β true  β 1    β 1         β 1   β
    βββββββ΄ββββββ΄ββββββββ΄βββββββ΄ββββββββββββ΄ββββββ

    Note that in regular Polars usage, a single string is parsed as a column name.

    >>> df.with_columns(
    ...     when = pl.col.foo > 2,
    ...     then = "foo",
    ...     otherwise = "bar"
    ... )
    shape: (3, 5)
    βββββββ¬ββββββ¬ββββββββ¬βββββββ¬ββββββββββββ
    β foo β bar β when  β then β otherwise β
    β --- β --- β ---   β ---  β ---       β
    β i64 β i64 β bool  β i64  β i64       β
    βββββββͺββββββͺββββββββͺβββββββͺββββββββββββ‘
    β 1   β 3   β false β 1    β 3         β
    β 3   β 4   β true  β 3    β 4         β
    β 4   β 0   β true  β 4    β 0         β
    βββββββ΄ββββββ΄ββββββββ΄βββββββ΄ββββββββββββ

    For consistency, `when-then` behaves in the same way.

    >>> df.with_columns(
    ...     pl.when(pl.col.foo > 2).then("foo").otherwise("bar").alias("val")
    ... )
    shape: (3, 3)
    βββββββ¬ββββββ¬ββββββ
    β foo β bar β val β
    β --- β --- β --- β
    β i64 β i64 β i64 β
    βββββββͺββββββͺββββββ‘
    β 1   β 3   β 3   β
    β 3   β 4   β 3   β
    β 4   β 0   β 4   β
    βββββββ΄ββββββ΄ββββββ

    :func:`lit` can be used to create string values.

    >>> df.with_columns(
    ...     pl.when(pl.col.foo > 2)
    ...     .then(pl.lit("foo"))
    ...     .otherwise(pl.lit("bar"))
    ...     .alias("val")
    ... )
    shape: (3, 3)
    βββββββ¬ββββββ¬ββββββ
    β foo β bar β val β
    β --- β --- β --- β
    β i64 β i64 β str β
    βββββββͺββββββͺββββββ‘
    β 1   β 3   β bar β
    β 3   β 4   β foo β
    β 4   β 0   β foo β
    βββββββ΄ββββββ΄ββββββ

    Multiple `when-then` statements can be chained.

    >>> df.with_columns(
    ...     pl.when(pl.col.foo > 2)
    ...     .then(1)
    ...     .when(pl.col.bar > 2)
    ...     .then(4)
    ...     .otherwise(-1)
    ...     .alias("val")
    ... )
    shape: (3, 3)
    βββββββ¬ββββββ¬ββββββ
    β foo β bar β val β
    β --- β --- β --- β
    β i64 β i64 β i32 β
    βββββββͺββββββͺββββββ‘
    β 1   β 3   β 4   β
    β 3   β 4   β 1   β
    β 4   β 0   β 1   β
    βββββββ΄ββββββ΄ββββββ

    In the case of `foo=3` and `bar=4`, both conditions are True but the first value
    (i.e. 1) is picked.

    >>> df.with_columns(
    ...     when1 = pl.col.foo > 2,
    ...     then1 = 1,
    ...     when2 = pl.col.bar > 2,
    ...     then2 = 4,
    ...     otherwise = -1
    ... )
    shape: (3, 7)
    βββββββ¬ββββββ¬ββββββββ¬ββββββββ¬ββββββββ¬ββββββββ¬ββββββββββββ
    β foo β bar β when1 β then1 β when2 β then2 β otherwise β
    β --- β --- β ---   β ---   β ---   β ---   β ---       β
    β i64 β i64 β bool  β i32   β bool  β i32   β i32       β
    βββββββͺββββββͺββββββββͺββββββββͺββββββββͺββββββββͺββββββββββββ‘
    β 1   β 3   β false β 1     β true  β 4     β -1        β
    β 3   β 4   β true  β 1     β true  β 4     β -1        β
    β 4   β 0   β true  β 1     β false β 4     β -1        β
    βββββββ΄ββββββ΄ββββββββ΄ββββββββ΄ββββββββ΄ββββββββ΄ββββββββββββ

    The `otherwise` statement is optional and defaults to `.otherwise(None)`
    if not given.

    This idiom is commonly used to null out values.

    >>> df.with_columns(pl.when(pl.col.foo == 3).then("bar"))
    shape: (3, 2)
    βββββββ¬βββββββ
    β foo β bar  β
    β --- β ---  β
    β i64 β i64  β
    βββββββͺβββββββ‘
    β 1   β null β
    β 3   β 4    β
    β 4   β null β
    βββββββ΄βββββββ

    `when` accepts keyword arguments as shorthand for equality conditions.

    >>> df.with_columns(pl.when(foo=3).then("bar"))
    shape: (3, 2)
    βββββββ¬βββββββ
    β foo β bar  β
    β --- β ---  β
    β i64 β i64  β
    βββββββͺβββββββ‘
    β 1   β null β
    β 3   β 4    β
    β 4   β null β
    βββββββ΄βββββββ

    Multiple predicates passed to `when` are combined with `&`

    >>> df.with_columns(
    ...     pl.when(pl.col.foo > 2, pl.col.bar < 3) # when((pred1) & (pred2))
    ...     .then(pl.lit("Yes"))
    ...     .otherwise(pl.lit("No"))
    ...     .alias("val")
    ... )
    shape: (3, 3)
    βββββββ¬ββββββ¬ββββββ
    β foo β bar β val β
    β --- β --- β --- β
    β i64 β i64 β str β
    βββββββͺββββββͺββββββ‘
    β 1   β 3   β No  β
    β 3   β 4   β No  β
    β 4   β 0   β Yes β
    βββββββ΄ββββββ΄ββββββ

    It could also be thought of as an implicit :func:`all_horizontal` being present.

    >>> df.with_columns(
    ...     when = pl.all_horizontal(pl.col.foo > 2, pl.col.bar < 3)
    ... )
    shape: (3, 3)
    βββββββ¬ββββββ¬ββββββββ
    β foo β bar β when  β
    β --- β --- β ---   β
    β i64 β i64 β bool  β
    βββββββͺββββββͺββββββββ‘
    β 1   β 3   β false β
    β 3   β 4   β false β
    β 4   β 0   β true  β
    βββββββ΄ββββββ΄ββββββββ

    Structs can be used as a way to return multiple values.

    Here we swap the "foo" and "bar" values when "foo" is greater than 2.

    >>> df.with_columns(
    ...     pl.when(pl.col.foo > 2)
    ...     .then(pl.struct(foo="bar", bar="foo"))
    ...     .otherwise(pl.struct("foo", "bar"))
    ...     .struct.unnest()
    ... )
    shape: (3, 2)
    βββββββ¬ββββββ
    β foo β bar β
    β --- β --- β
    β i64 β i64 β
    βββββββͺββββββ‘
    β 1   β 3   β
    β 4   β 3   β
    β 0   β 4   β
    βββββββ΄ββββββ

    The struct fields are given the same name as the target columns, which are then
    unnested.

    >>> df.with_columns(
    ...     when = pl.col.foo > 2,
    ...     then = pl.struct(foo="bar", bar="foo"),
    ...     otherwise = pl.struct("foo", "bar")
    ... )
    shape: (3, 5)
    βββββββ¬ββββββ¬ββββββββ¬ββββββββββββ¬ββββββββββββ
    β foo β bar β when  β then      β otherwise β
    β --- β --- β ---   β ---       β ---       β
    β i64 β i64 β bool  β struct[2] β struct[2] β
    βββββββͺββββββͺββββββββͺββββββββββββͺββββββββββββ‘
    β 1   β 3   β false β {3,1}     β {1,3}     β
    β 3   β 4   β true  β {4,3}     β {3,4}     β
    β 4   β 0   β true  β {0,4}     β {4,0}     β
    βββββββ΄ββββββ΄ββββββββ΄ββββββββββββ΄ββββββββββββ

    The output name of a `when-then` expression comes from the first `then` branch.

    Here we try to set all columns to 0 if any column contains a value less than 2.

    >>> df.with_columns( # doctest: +SKIP
    ...    pl.when(pl.any_horizontal(pl.all() < 2))
    ...    .then(0)
    ...    .otherwise(pl.all())
    ... )
    # ComputeError: the name 'literal' passed to `LazyFrame.with_columns` is duplicate

    :meth:`.name.keep` could be used to give preference to the column expression.

    >>> df.with_columns(
    ...    pl.when(pl.any_horizontal(pl.all() < 2))
    ...    .then(0)
    ...    .otherwise(pl.all())
    ...    .name.keep()
    ... )
    shape: (3, 2)
    βββββββ¬ββββββ
    β foo β bar β
    β --- β --- β
    β i64 β i64 β
    βββββββͺββββββ‘
    β 0   β 0   β
    β 3   β 4   β
    β 0   β 0   β
    βββββββ΄ββββββ

    The logic could also be changed to move the column expression inside `then`.

    >>> df.with_columns(
    ...     pl.when(pl.any_horizontal(pl.all() < 2).not_())
    ...     .then(pl.all())
    ...     .otherwise(0)
    ... )
    shape: (3, 2)
    βββββββ¬ββββββ
    β foo β bar β
    β --- β --- β
    β i64 β i64 β
    βββββββͺββββββ‘
    β 0   β 0   β
    β 3   β 4   β
    β 0   β 0   β
    βββββββ΄ββββββ
    )r   ΪplΪWhenΪplrΪwhen)r	   r   Ϊ	conditions      ϊY/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/polars/functions/whenthen.pyr   r      s1    υ\
 =ΈjΠXΘKΠXΠXIέ738IΡ&Τ&Ρ'Τ'Π'σ    )r	   r
   r   r   r   r   )Ϊ
__future__r   Ϊ
contextlibΪtypingr   r   Ϊpolars._reexportΪ	_reexportr   Ϊpolars._utils.parser   ΪsuppressΪImportErrorΪpolars.polarsΪpolarsr   Ϊcollections.abcr   Ϊpolars._typingr   r   © r   r   ϊ<module>r#      s+  πΨ "Π "Π "Π "Π "Π "ΰ Π Π Π Ψ %Π %Π %Π %Π %Π %Π %Π %ΰ Π Π Π Π Π Ψ LΠ LΠ LΠ LΠ LΠ LΰZΤΡ%Τ%π  π  ΨΠΠΠΠΠπ π  π  ρ  τ  π  π  π  π  π  π  ψψψπ  π  π  π  π π .Ψ(Π(Π(Π(Π(Π(ΰ-Π-Π-Π-Π-Π-πO(π O(π O(π O(π O(π O(s   ―AΑAΑ	A