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

Pandas:基于Wi与Li列生成SET列并处理NaN值问题

解决DataFrame生成SET列并正确处理NaN值的问题

你遇到的NaN处理问题其实很常见,用循环逐行处理不仅效率低,还容易遗漏NaN的判断逻辑。咱们可以用pandas的向量化操作来完美解决这个需求,既简洁又能准确符合你设定的三个规则。

方案1:使用np.where嵌套判断(最直观)

这个方法先判断Wi和Li是否都不为空,再根据大小关系赋值,否则直接返回NaN:

import pandas as pd
import numpy as np

# 构造你的示例数据
df = pd.DataFrame({
    'W1': [6, np.nan],
    'W2': [6, np.nan],
    'W3': [3, np.nan],
    'W4': [6, 6],
    'L1': [7, np.nan],
    'L2': [3, np.nan],
    'L3': [6, np.nan],
    'L4': [7, np.nan]
})

# 循环生成SET1到SET4列
for i in range(1, 5):
    w_col = f"W{i}"
    l_col = f"L{i}"
    # 第一层判断:Wi和Li都不为NaN时才进行大小比较
    df[f"SET{i}"] = np.where(
        df[w_col].notna() & df[l_col].notna(),
        # 第二层判断:Wi>Li返回1.0,否则0.0
        np.where(df[w_col] > df[l_col], 1.0, 0.0),
        # 只要有一个是NaN,就返回NaN
        np.nan
    )

# 查看最终的SET列结果
print(df[["SET1", "SET2", "SET3", "SET4"]])

运行这段代码后,输出完全符合你的预期:

SET1  SET2  SET3  SET4
0   0.0   0.0   1.0   0.0
1   NaN   NaN   NaN   1.0

方案2:用pd.Series.mask简化逻辑

如果你觉得嵌套np.where有点绕,也可以先生成比较结果,再把含NaN的位置替换成NaN:

for i in range(1, 5):
    w_col = f"W{i}"
    l_col = f"L{i}"
    # 先得到Wi>Li的布尔结果,转成float(True→1.0,False→0.0)
    set_result = (df[w_col] > df[l_col]).astype(float)
    # 把Wi或Li为NaN的位置替换成NaN
    df[f"SET{i}"] = set_result.mask(df[w_col].isna() | df[l_col].isna())

这个方法的逻辑是:先处理所有非NaN的比较,再用mask方法将存在NaN的位置覆盖为NaN,同样能达到要求。

为什么你的循环方案处理不好NaN?

当你用普通循环逐行处理时,需要额外判断每个元素是否为NaN,比如if pd.notna(row[w_col]) and pd.notna(row[l_col]),否则直接赋值NaN。但这种逐行循环的方式在DataFrame数据量大的时候会非常慢,而且代码冗余。而上面的向量化操作是批量处理整个列,pandas会自动处理NaN的逻辑,既高效又不易出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:26:03