Polars 1.22.0中的空感知求值是否存在缺陷?
Polars 1.22.0中的空感知求值是否存在缺陷?
这是个非常敏锐的观察!你遇到的这个差异其实并不是Polars空感知求值的缺陷,而是和Polars中|、&这两个逻辑运算符的特殊设计有关——它们是短路逻辑运算符,行为和你提到的算术/比较运算符完全不同。
为什么pl.lit(None) | pl.lit(True)返回True?
在Polars中,|代表短路逻辑或,它的求值规则是:
- 只要某一个操作数能直接确定整个表达式的结果,就会短路返回该结果,不再评估另一个操作数。
- 当你写
pl.lit(None) | pl.lit(True)时,虽然左边是null(空值),但右边是明确的True(逻辑真值)。根据逻辑或的规则,只要有一个操作数为真,整个表达式的结果就为真,因此Polars会直接返回True,不会因为左边的null触发空感知的null返回规则。
为什么pl.lit(None) & pl.lit(True)返回None?
而&代表短路逻辑与,它的求值规则是:
- 只有当第一个操作数为真时,才会继续评估第二个操作数;如果第一个操作数是假或null,就直接返回对应结果。
- 当左边是null时,Polars将其视为“未知”的逻辑值——未知与任何值进行逻辑与运算,结果仍然是未知(即null),因此返回None,这和你的预期一致。
其他运算符为什么都返回null?
你提到的比较运算符(>, <, ==)和算术运算符(+, -, *, /)都是逐元素的空感知运算,它们严格遵循“只要任意一个操作数为null,结果就为null”的规则,所以这些操作的结果都是null,和你预期的空感知行为完全一致。
如何实现空感知的逻辑或?
如果你需要让逻辑或操作也遵循“只要有一个null就返回null”的空感知规则,可以使用Polars提供的pl.or_()(或pl.logical_or())函数,而不是|运算符:
pl.DataFrame(data={}).select(a=pl.lit(None).or_(pl.lit(True))
这个表达式会返回null,完全符合你预期的空感知求值行为。
备注:内容来源于stack exchange,提问作者Silverdust
相关产品推荐
相关产品推荐

