如何在Polars的list.eval中正确实现if-else逻辑?
问题:Polars List列元素的if-else转换(哈希/替换unknown)
需要对Polars DataFrame的List类型列元素执行if-else转换:元素为unknown时返回-1,否则返回该元素的哈希值。使用list.eval配合pl.when实现时能得到结果,但触发警告,求正确实现方式。
示例DataFrame
import polars as pl df = pl.DataFrame({"Tokens": [["a", "b", "c"], ["a"], ["unknown"]]})
输出:
shape: (3, 1) ┌─────────────────┐ │ Tokens │ │ --- │ │ list[str] │ ╞═════════════════╡ │ ["a", "b", "c"] │ │ ["a"] │ │ ["unknown"] │ └─────────────────┘
尝试的代码及警告
代码:
df.with_columns(pl.col("Tokens").list.eval(pl.when(pl.element() == 'unknown').then(pl.lit(0, dtype=pl.UInt64)).otherwise(pl.element().hash())))
触发警告:
The predicate '[(col("")) == (Utf8(unknown))]' in 'when->then->otherwise' is not a valid aggregation and might produce a different number of rows than the groupby operation would. This behavior is experimental and may be subject to change
输出结果:
shape: (3, 1) ┌───────────────────────────────────┐ │ Tokens │ │ --- │ │ list[u64] │ ╞═══════════════════════════════════╡ │ [1588745937650624681, 1558575890… │ │ [1588745937650624681] │ │ [0] │ └───────────────────────────────────┘
正确实现方式
方法1:在list.eval中使用pl.col("")替代pl.element()
list.eval内部将每个列表视为一个分组,使用pl.col("")明确指向分组内的元素,可避免警告:
df.with_columns( pl.col("Tokens").list.eval( pl.when(pl.col("") == "unknown") .then(pl.lit(-1, dtype=pl.Int64)) .otherwise(pl.col("").hash()) ) )
这里将返回类型改为pl.Int64,因为-1是负数,无法用无符号整数类型存储。
方法2:使用list.map_elements(Python层面处理)
如果更习惯Python函数式写法,可通过list.map_elements调用自定义函数处理每个元素:
def process_token(token): return -1 if token == "unknown" else hash(token) df.with_columns( pl.col("Tokens").list.map_elements(process_token, return_dtype=pl.Int64) )
方法3:使用list.eval配合pl.element()并添加parallel=True
在list.eval中添加parallel=True参数,Polars在并行模式下会正确处理元素级操作,也能消除警告:
df.with_columns( pl.col("Tokens").list.eval( pl.when(pl.element() == "unknown") .then(pl.lit(-1, dtype=pl.Int64)) .otherwise(pl.element().hash()), parallel=True ) )
以上三种方法都能得到正确结果且无警告,输出示例:
shape: (3, 1) ┌───────────────────────────────────┐ │ Tokens │ │ --- │ │ list[i64] │ ╞═══════════════════════════════════╡ │ [1588745937650624681, 1558575890… │ │ [1588745937650624681] │ │ [-1] │ └───────────────────────────────────┘
内容的提问来源于stack exchange,提问作者Zeyan Li
相关产品推荐
相关产品推荐

