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

如何在np.where中处理含可选None值的多条件判断?

问题描述

我需要给DataFrame新增一个基于条件的列,已经在外部定义了如下条件列表:

conditions = [
    {"year": 2016, "price": 30000, "fuel": "Petrol", "result": 12},
    {"year": 2017, "price": 45000, "fuel": "Elektricity", "result": 18},
    {"year": 2018, "price": None, "fuel": "Petrol", "result": 14}
]

目前我用这段代码生成新列:

df['new_column'] = np.where(
    (df['year'] == cond['year']) & (df['price'] > cond['price']) & (df['fuel description'] == cond['fuel']),
    cond['result'],
    df['new_column']
)

但条件里可能存在None值(比如示例中2018年的price),这时需要忽略该条件,对应的代码要去掉价格判断的部分:

df['new_column'] = np.where(
    (df['year'] == cond['year']) & (df['fuel description'] == cond['fuel']),
    cond['result'],
    df['new_column']
)

而且可能有多个条件为None的情况,我不想写一堆if-else分支,想知道有没有办法在公式里自动忽略值为None的条件,而不是只能像下面这样处理:

if cond['price'] is not None:
    df['new_column'] = np.where(
        (df['year'] == cond['year']) & (df['price'] > cond['price']) & (df['fuel description'] == cond['fuel']),
        cond['result'],
        df['new_column']
    )
else:
    df['new_column'] = np.where(
        (df['year'] == cond['year']) & (df['fuel description'] == cond['fuel']),
        cond['result'],
        df['new_column']
    )
解决方案

可以通过动态构建条件表达式自动忽略None值的条件,无需编写大量if-else分支。核心逻辑是遍历每个条件字典的键值对,仅保留非None的条件,再将这些条件用逻辑与(&)拼接。

基础实现代码

import numpy as np
import pandas as pd

# 示例DataFrame
df = pd.DataFrame({
    'year': [2016, 2017, 2018, 2019],
    'price': [35000, 50000, 28000, 32000],
    'fuel description': ['Petrol', 'Elektricity', 'Petrol', 'Diesel'],
    'new_column': [0, 0, 0, 0]  # 初始化新列
})

conditions = [
    {"year": 2016, "price": 30000, "fuel": "Petrol", "result": 12},
    {"year": 2017, "price": 45000, "fuel": "Elektricity", "result": 18},
    {"year": 2018, "price": None, "fuel": "Petrol", "result": 14}
]

# 遍历每个条件规则
for cond in conditions:
    condition_parts = []
    # 逐个判断字段是否为None,非None则生成对应布尔表达式
    if cond['year'] is not None:
        condition_parts.append(df['year'] == cond['year'])
    if cond['price'] is not None:
        condition_parts.append(df['price'] > cond['price'])
    if cond['fuel'] is not None:
        condition_parts.append(df['fuel description'] == cond['fuel'])
    
    # 拼接所有条件为最终判断表达式
    final_condition = np.logical_and.reduce(condition_parts)
    # 更新新列
    df['new_column'] = np.where(final_condition, cond['result'], df['new_column'])

print(df)

代码说明

  1. 遍历每个条件字典,对year、price、fuel字段逐一判断是否为None,非None则生成对应的布尔判断表达式,加入条件列表。
  2. 用np.logical_and.reduce()将所有条件表达式拼接成最终的逻辑与判断,自动忽略所有None对应的条件。
  3. 用np.where()根据最终条件更新新列,无论有多少个None条件,都无需额外分支判断。

扩展优化(适配更多字段)

如果需要支持更多条件字段,可以通过映射字典统一管理字段与判断逻辑,避免重复代码:

import numpy as np
import pandas as pd

df = pd.DataFrame({
    'year': [2016, 2017, 2018, 2019],
    'price': [35000, 50000, 28000, 32000],
    'fuel description': ['Petrol', 'Elektricity', 'Petrol', 'Diesel'],
    'new_column': [0, 0, 0, 0]
})

conditions = [
    {"year": 2016, "price": 30000, "fuel": "Petrol", "result": 12},
    {"year": 2017, "price": 45000, "fuel": "Elektricity", "result": 18},
    {"year": 2018, "price": None, "fuel": "Petrol", "result": 14}
]

# 定义字段与对应判断逻辑的映射
condition_mappings = {
    'year': lambda df_val, cond_val: df_val == cond_val,
    'price': lambda df_val, cond_val: df_val > cond_val,
    'fuel': lambda df_val, cond_val: df_val == cond_val
}

for cond in conditions:
    condition_parts = []
    for key, judge_func in condition_mappings.items():
        cond_val = cond.get(key)
        if cond_val is not None:
            # 处理字段名与DataFrame列名不一致的情况(如fuel对应fuel description)
            df_col = 'fuel description' if key == 'fuel' else key
            condition_parts.append(judge_func(df[df_col], cond_val))
    final_condition = np.logical_and.reduce(condition_parts)
    df['new_column'] = np.where(final_condition, cond['result'], df['new_column'])

print(df)

新增条件字段时,只需在condition_mappings中添加对应的字段和判断逻辑即可,代码扩展性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:51:17