You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polars中when-then-otherwise异常及单表达式实现咨询

Polars:when/then分支求值问题与单行表达式解决方案

问题场景

测试代码

import polars as pl
import numpy as np

u = 2

df = (pl.DataFrame(dict(
  j=np.random.randint(10, 99, 10)
  ))
  .with_row_count()
  .with_columns(k=(pl.col('j') % 10) == u)
  .with_columns(l=pl.col('k').any())
  )
print(df)

print(df
  .with_columns(i=pl
    .when(pl.col('k').any())
    .then(pl.col('row_nr') > pl.col('row_nr').where(pl.col('k')).first())
    .otherwise(None)
    )
  )

异常情况

当设置u=0且j%10无匹配项时,触发如下错误:

exceptions.ComputeError: cannot evaluate two series of different lengths (10 and 0)

Error originated in expression: '[(col("row_nr")) > (col("row_nr").filter(col("k")).first())]'

疑问解答

1. 为何pl.when().then().otherwise()在when条件为false时仍会求值then分支?

Polars的表达式执行逻辑和Python原生if/else不同:Polars会预先解析并计算所有分支的表达式,再根据when的条件选择最终结果,而非跳过不满足条件的分支。

也就是说,无论when条件是否成立,then和otherwise里的表达式都会先被执行一遍。当u=0且无匹配项时,pl.col('row_nr').where(pl.col('k'))生成长度为0的Series,调用first()后仍为长度0的Series,和长度10的row_nr做比较时就会抛出长度不匹配的错误。

2. 能否在单个表达式内处理该场景,无需外部Python逻辑?

可以,核心是确保then分支的表达式在任何情况下都能生成合法的、长度匹配的Series。通过fill_null或coalesce给空Series的first()结果设置默认值,就能避免报错:

print(df
  .with_columns(i=pl
    .when(pl.col('k').any())
    .then(pl.col('row_nr') > pl.col('row_nr').where(pl.col('k')).first().fill_null(-1))
    .otherwise(None)
    )
  )

或者用coalesce更明确地处理空值:

print(df
  .with_columns(i=pl
    .when(pl.col('k').any())
    .then(pl.col('row_nr') > pl.coalesce(pl.col('row_nr').where(pl.col('k')).first(), pl.lit(-1)))
    .otherwise(None)
    )
  )

因为when的条件是pl.col('k').any(),只有存在匹配项时才会进入then分支,此时first()会返回有效值,默认值-1不会被实际使用;无匹配项时,otherwise直接返回None,完全避开了then分支的计算结果。


内容的提问来源于stack exchange,提问作者levant pied

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 23:17:40