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

Pandas DataFrame条件格式化函数传递额外参数时触发NameError错误的解决求助

Pandas DataFrame条件格式化函数传递额外参数时触发NameError错误的解决求助

你遇到的这个NameError问题,根源在于Python函数默认参数的求值时机——默认参数是在函数定义的时候就计算的,而不是调用的时候。

你在定义condFormat时写了def condFormat(s, df=dfdefs),这行代码在Python解析函数定义的时候就会尝试查找dfdefs这个变量,但此时dfdefs还没有被创建(它是在main函数内部才会从数据库读取赋值的),所以自然会抛出“name 'dfdefs' is not defined”的错误。

方案一:调用时显式传递参数(推荐)

修改condFormat函数,去掉默认的df参数,然后在调用applymap的时候通过关键字参数把dfdefs传递进去。同时注意:df.style.applymap()返回的是一个Styler对象,不会修改原DataFrame,你需要用这个Styler对象来生成HTML,否则导出的内容不会包含样式。

修改后的完整代码:

def condFormat(s, df):
    dcolors = {"GREEN": "rgb(146, 208, 80)",
               "YELLOW": "rgb(255, 255, 153)",
               "RED": "rgb(218, 150, 148)",
               None: "rgb(255, 255, 255)"}
    dftemp = df.query("STATUS == @s")
    scolor = dcolors[dftemp["COLOR"].iloc[0]]
    return "background-color: " + scolor

def main():
    dfhealth = pd.read_sql("SELECT name, status FROM health", conn)
    dfdefs = pd.read_sql("SELECT status, color FROM definitions", conn)
    # 调用applymap时显式传递df参数
    styled_df = dfhealth.style.applymap(condFormat, df=dfdefs)
    # 使用Styler对象生成HTML
    html = styled_df.to_html()
    return html

方案二:避免定义时的默认参数求值

如果一定要保留默认参数的形式,可以把默认值设为None,然后在函数内部做判断,避免定义时就查找未存在的变量:

def condFormat(s, df=None):
    if df is None:
        raise ValueError("必须传入df参数,用于匹配状态与颜色的映射")
    dcolors = {"GREEN": "rgb(146, 208, 80)",
               "YELLOW": "rgb(255, 255, 153)",
               "RED": "rgb(218, 150, 148)",
               None: "rgb(255, 255, 255)"}
    dftemp = df.query("STATUS == @s")
    scolor = dcolors[dftemp["COLOR"].iloc[0]]
    return "background-color: " + scolor

def main():
    dfhealth = pd.read_sql("SELECT name, status FROM health", conn)
    dfdefs = pd.read_sql("SELECT status, color FROM definitions", conn)
    styled_df = dfhealth.style.applymap(condFormat, df=dfdefs)
    html = styled_df.to_html()
    return html

额外优化:提前构建状态-颜色映射字典

每次调用condFormat都执行df.query()会有点低效,尤其是当数据量较大的时候。你可以在main函数里先把dfdefs转换成字典,直接通过状态值获取颜色名称,提升效率:

def main():
    dfhealth = pd.read_sql("SELECT name, status FROM health", conn)
    dfdefs = pd.read_sql("SELECT status, color FROM definitions", conn)
    # 提前构建状态到颜色名称的映射字典
    status_to_color = dfdefs.set_index("STATUS")["COLOR"].to_dict()
    
    def condFormat(s):
        dcolors = {"GREEN": "rgb(146, 208, 80)",
                   "YELLOW": "rgb(255, 255, 153)",
                   "RED": "rgb(218, 150, 148)",
                   None: "rgb(255, 255, 255)"}
        # 直接通过字典获取颜色名称,不存在则用默认白色
        color_name = status_to_color.get(s)
        scolor = dcolors.get(color_name, dcolors[None])
        return f"background-color: {scolor}"
    
    styled_df = dfhealth.style.applymap(condFormat)
    html = styled_df.to_html()
    return html

备注:内容来源于stack exchange,提问作者Kes Perron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 11:53:04