如何将Polars Expression应用到Polars Series以实现通用函数?
如何在Polars中实现泛化函数将Expr应用到Series
要实现apply_expr函数,核心是掌握Polars中将Expr应用到Series的方法,同时修正调用时的Expr写法问题,具体实现如下:
1. 核心实现逻辑
Polars提供了两种直接将Expr作用于Series的方式:
- 调用Expr的
evaluate方法,传入目标Series - 将Series转为单列DataFrame,用
select执行Expr后提取标量结果
2. 完整可运行代码
结合你的需求,修正后的apply_expr函数及调用示例如下:
import polars as pl series = pl.Series("x", [0, -1, 1, -1]) def apply_expr(series: pl.Series, default: int, expr: pl.Expr) -> int: # 使用evaluate执行Expr并获取结果 result = expr.evaluate(series) # 处理空Series的情况(聚合操作返回None) if result is None: return default # 类型校验,确保返回值符合预期 if isinstance(result, int): return result else: raise ValueError(f"{result=}, {type(result)=}, expected `int`.") # 注意:正确构造Expr需用pl.col指定列名,而非直接实例化pl.Expr() apply_expr(series, -1, pl.col("x").abs().max()) # 输出: 1
3. 关键细节说明
- Expr构造修正:你原代码中
pl.Expr().abs().max()是无效写法,Polars的Expr需要基于列引用创建(比如pl.col("x")),这样才能明确作用的目标列。 - 空值处理:当Series为空时,聚合操作(如
max())会返回None,此时函数返回传入的default值。 - 类型安全:保留了原函数的类型校验逻辑,避免返回非预期类型的值。
4. 备选实现方式(基于DataFrame操作)
如果你更习惯DataFrame的操作模式,也可以用以下写法:
def apply_expr(series: pl.Series, default: int, expr: pl.Expr) -> int: # 将Series转为单列DataFrame,执行Expr后提取标量 result = series.to_frame().select(expr).item() if result is None: return default if isinstance(result, int): return result else: raise ValueError(f"{result=}, {type(result)=}, expected `int`.")
内容的提问来源于stack exchange,提问作者bzm3r
相关产品推荐
相关产品推荐

