File size: 2,415 Bytes
b336134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
"""
Polars Expression Builder.
Builds programmatic expressions securely without raw eval/exec.
"""
from __future__ import annotations

import polars as pl

def build_polars_expression(operation: str, column: str, params: dict) -> pl.Expr:
    """Build programmatic expressions for increase, decrease, cast_type, and find_replace."""
    if operation == "increase":
        value = params.get("value", 10.0)
        is_percent = params.get("is_percent", True)
        if is_percent:
            return (pl.col(column) * (1 + value / 100)).alias(column)
        else:
            return (pl.col(column) + value).alias(column)
            
    elif operation == "decrease":
        value = params.get("value", 10.0)
        is_percent = params.get("is_percent", True)
        if is_percent:
            return (pl.col(column) * (1 - value / 100)).alias(column)
        else:
            return (pl.col(column) - value).alias(column)
            
    elif operation == "cast_type":
        target = params.get("target_dtype")
        dtype_map = {
            "Int64": pl.Int64,
            "Int32": pl.Int32,
            "Float64": pl.Float64,
            "Float32": pl.Float32,
            "String": pl.String,
            "Boolean": pl.Boolean,
            "Date": pl.Date,
        }
        pl_dtype = dtype_map.get(target)
        if pl_dtype is None:
            raise ValueError(f"Unsupported target dtype: {target}")
        return pl.col(column).cast(pl_dtype).alias(column)
        
    elif operation == "find_replace":
        old_val = params.get("old_value")
        new_val = params.get("new_value")
        is_numeric = params.get("is_numeric", False)
        
        if is_numeric:
            try:
                old_num = float(old_val)
                new_num = float(new_val)
                return pl.when(pl.col(column) == old_num).then(pl.lit(new_num)).otherwise(pl.col(column)).alias(column)
            except (ValueError, TypeError):
                raise ValueError("Values must be numeric for a numeric column replacement.")
        else:
            return (
                pl.when(pl.col(column).cast(pl.String) == str(old_val))
                .then(pl.lit(str(new_val)))
                .otherwise(pl.col(column))
                .alias(column)
            )
            
    else:
        raise ValueError(f"Unsupported operation for programmatic expression building: {operation}")