Python Polars v0.15.15中二进制标志列设置异常问题排查
Polars v0.15.15二进制标志列位运算异常原因解析
根本原因
这是Polars v0.15.x版本中列引用惰性解析的bug导致的:
- 当连续调用
with_column更新同一列时,第二次调用里的pl.col("flag")并没有指向第一次修改后的列值,而是仍然绑定到初始DataFrame中全为0的原始flag列。 - 实际执行逻辑变成所有行都执行了
(原始flag | 2) | 4,也就是0|2|4=6,最终导致flag列全为6,和预期结果不符。
调换顺序后正常的原因
先设置标志4再设置标志2时,第二次when的条件仅命中部分行(col1<1或col1>=3),此时otherwise分支会保留第一次修改后的flag值(4),而then分支虽然仍引用原始flag执行0|2=2,但最终合并时,命中条件的行实际是2|4=6,未命中的行保留4,刚好符合预期——本质还是bug的表现不一致,但核心问题始终是列引用未正确绑定到最新列值。
修复方案
- 升级Polars版本:v0.16及以上版本已经修复了这个列引用解析的bug,连续更新同一列时,
pl.col("col_name")会正确引用上一次修改后的列值。 - 临时替代写法:如果无法升级,每次更新时使用
with_columns(复数形式)并通过alias显式指定列名,确保表达式引用的是最新计算结果:
df = df.with_columns( pl.when((pl.col("col1") < 1) | (pl.col("col1") >= 3)) .then(pl.col("flag") | 2) .otherwise(pl.col("flag")) .alias("flag") ) df = df.with_columns( pl.when(pl.col("col1") > -1) .then(pl.col("flag") | 4) .otherwise(pl.col("flag")) .alias("flag") )
内容的提问来源于stack exchange,提问作者FObersteiner
相关产品推荐
相关产品推荐

