ó
    à'·h±6  ã                  óà   • S SK Jr  S SKrS SKJrJr  S SKJr  S SK	J
r
  \R                  " \5         S SKJr  SSS5        \(       a  S SKJr  S SKJr        SS jrg! , (       d  f       N-= f)	é    )ÚannotationsN)ÚTYPE_CHECKINGÚAny)Ú,parse_predicates_constraints_into_expression)ÚIterable)ÚIntoExprColumnc                 ól   • [        U 0 UD6n[        R                  " [        R                  " U5      5      $ )u*.  
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)Ú
predicatesÚconstraintsÚ	conditions      ÚlC:\Users\julio\OneDrive\Documentos\Trabajo\Ideas Frescas\venv\Lib\site-packages\polars/functions/whenthen.pyr   r      s,   € ô\
 =¸jÐXÈKÑX€IÜ7Š7”3—8’8˜IÓ&Ó'Ð'ó    )r   z0IntoExprColumn | Iterable[IntoExprColumn] | boolr   r   Úreturnzpl.When)Ú
__future__r   Ú
contextlibÚtypingr   r   Úpolars._reexportÚ	_reexportr
   Úpolars._utils.parser   ÚsuppressÚImportErrorÚpolars._plrÚ_plrr   Úcollections.abcr   Úpolars._typingr   r   © r   r   Ú<module>r!      sa   ðÝ "ã ß %å Ý Là×Ò˜Õ%Ý÷ &ö Ý(å-ðO(ØAðO(àðO(ð õO(÷ &Õ%ús   ±AÁ
A-