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

Polars中when-then-otherwise条件替换列值出错及正确实现

问题:Polars条件更新字段的错误分析与解决

初始DataFrame

创建代码:

import polars as pl

df = pl.DataFrame({'r_num':['Yes', '', 'Yes'], 'pin': ['Yes','',''],'fin':['','','']})

对应的DataFrame结构:

shape: (3, 3)
┌───────┬─────┬─────┐
│ r_num ┆ pin ┆ fin │
│ ---   ┆ --- ┆ --- │
│ str   ┆ str ┆ str │
╞═══════╪═════╪═════╡
│ Yes   ┆ Yes ┆     │
│       ┆     ┆     │
│ Yes   ┆     ┆     │
└───────┴─────┴─────┘

需求说明

需要筛选出满足以下条件的行:

  • r_num等于Yes
  • pin等于Yes
  • fin为空字符串

将这些行的r_num和pin字段设置为空字符串。

尝试的代码及错误结果

我试了这段代码:

df.with_columns(
    pl.when((pl.col('r_num')=='Yes') & (pl.col('pin')=='Yes') & (pl.col('fin') !='Yes'))
    .then(pl.col('r_num')=='')
    .otherwise(pl.col('r_num'))
)

得到错误结果:

shape: (3, 3)
┌───────┬─────┬─────┐
│ r_num ┆ pin ┆ fin │
│ ---   ┆ --- ┆ --- │
│ str   ┆ str ┆ str │
╞═══════╪═════╪═════╡
│ false ┆ Yes ┆     │
│       ┆     ┆     │
│ Yes   ┆     ┆     │
└───────┴─────┴─────┘

为什么r_num会被填充成false?

另外,我在Pandas里是这么实现的,能得到正确结果:

df_pd = df.to_pandas()
df_pd.loc[(df_pd['r_num']=='Yes') & (df_pd['pin']=='Yes') & (df_pd['fin']!='Yes'),['r_num','pin']] = ''

期望的正确结果:

shape: (3, 3)
┌───────┬─────┬─────┐
│ r_num ┆ pin ┆ fin │
│ ---   ┆ --- ┆ --- │
│ str   ┆ str ┆ str │
╞═══════╪═════╪═════╡
│       ┆     ┆     │
│       ┆     ┆     │
│ Yes   ┆     ┆     │
└───────┴─────┴─────┘

错误原因

你写的.then(pl.col('r_num')=='')是一个布尔比较表达式,它会判断r_num是否等于空字符串,返回的是布尔值(True或False),而不是把字段设置为空字符串。第一行的r_num是Yes,和空字符串比较结果是False,所以就被填充成了false。

另外,你条件里的pl.col('fin') !='Yes'其实不符合需求,应该写成pl.col('fin') == ''来匹配空字符串的条件。

正确的Polars实现方法

方法1:单独更新每个字段

直接在then里返回空字符串,而非做比较:

df = df.with_columns(
    # 更新r_num
    pl.when((pl.col('r_num') == 'Yes') & (pl.col('pin') == 'Yes') & (pl.col('fin') == ''))
    .then('')
    .otherwise(pl.col('r_num'))
    .alias('r_num'),
    # 更新pin
    pl.when((pl.col('r_num') == 'Yes') & (pl.col('pin') == 'Yes') & (pl.col('fin') == ''))
    .then('')
    .otherwise(pl.col('pin'))
    .alias('pin')
)

方法2:批量处理多个字段(更简洁)

用列表推导式批量处理需要更新的字段,避免重复写条件:

condition = (pl.col('r_num') == 'Yes') & (pl.col('pin') == 'Yes') & (pl.col('fin') == '')

df = df.with_columns(
    [
        pl.when(condition).then('').otherwise(pl.col(col)).alias(col)
        for col in ['r_num', 'pin']
    ]
)

方法3:使用where反向筛选

利用where方法,当条件不满足时保留原字段,满足时替换为空:

condition = (pl.col('r_num') == 'Yes') & (pl.col('pin') == 'Yes') & (pl.col('fin') == '')

df = df.with_columns(
    pl.col(['r_num', 'pin']).where(~condition, '')
)

运行以上任意一种方法,都能得到你期望的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:15:41