长 .when().then().when().then().otherwise() 链的替代方案

2024-01-11

是否有一些聪明的替代方法可以编写长的when().then().otherwise()链而不对值进行硬编码,请参见下面的示例:

假设我们有以下数据框

df = pl.DataFrame(
    {
        "Market":["AT", "AT", "DE", "DE", "CA", "DE", "UK", "US"],
        "Number of Days":[1, 2, 3, 4, 3, 4, 2, 1],
        
    }
)

用户将一些条件定义为不同国家的字典

params = {
    "AT":{"Value": 1},
    "DE":{"Value": 2},
    "CA":{"Value": 3},
    "UK":{"Value": 1},
    "US":{"Value": 2}
}

然后我对国家/地区进行硬编码并使用 Polars .with_columns() 中的国家/地区,如下所示:

(
    df
    .with_columns(
        [
            pl.when(pl.col("Market") == "AT").then(pl.col("Number of Days") + params["AT"]["Value"])
            .when(pl.col("Market") == "DE").then(pl.col("Number of Days") + params["DE"]["Value"])
            .when(pl.col("Market") == "CA").then(pl.col("Number of Days") + params["CA"]["Value"])
            .when(pl.col("Market") == "UK").then(pl.col("Number of Days") + params["UK"]["Value"])
            .when(pl.col("Market") == "US").then(pl.col("Number of Days") + params["US"]["Value"])
            .otherwise(None)
            .alias("New Column")
        ]
    )
)

有没有办法让我不对 .with_columns 中的国家/地区进行硬编码,而是以某种方式循环字典并根据提供的值创建表达式?

我尝试了下面的内容,但它说我有重复的列名。

exprs = []
for market, data in params.items():
    condition = (pl.col("Market") == market)
    result = (pl.col("Number of Days") + data["Value"])
    expr = pl.when(condition).then(result)
    exprs.append(expr)

df.with_columns(exprs)

您可以使用map_dict https://pola-rs.github.io/polars/py-polars/html/reference/expressions/api/polars.Expr.map_dict.html#polars.Expr.map_dict

(
    df
        .with_columns((
            pl.col("Number of Days") + 
            pl.col("Market")
                .map_dict({x:y['Value'] for x,y in params.items()})
            )
            .alias("New Column")
        )
)

或者,您可以将 params 设置为其自己的 df,然后加入它们。map_dict工作原理是将你的 dict 转换为 df 然后加入它们,但根据你的参数来自哪里,这可能是首选。

paramsdf = pl.DataFrame({'Market':params.keys(), 
                         'Value':[x['Value'] for x in params.values()]})
(
    df.join(paramsdf, on="Market")
        .with_columns((pl.col("Number of Days")+ pl.col("Value")).alias("New Column"))
        .drop("Value")
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

长 .when().then().when().then().otherwise() 链的替代方案 的相关文章

随机推荐