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

pandas表格渲染调用render()报错TypeError:第一个参数必须可调用

问题解析与解决

问题描述

同一程序中,第一段代码可正常生成用于HTML邮件的pandas样式表格,但对筛选后的DataFrame应用相同逻辑生成第二个表格时,调用render()方法抛出错误:

TypeError: the first argument must be callable

可正常运行的第一段代码

import numpy as np
import pandas as pd
import locale


money = [10000000, 2200000000, 10241100000.4521, 20224400000.75895]
honey = [30.6427984591421, 9584.28792256921, 37008.6603, 211200.2304295]
ltrs = ["a", "b", "a", "c"]
YRMO = ["202211", "202210", "202211", "202210"]
org = ['Main','Main', 'Jr', 'Jr']
df = pd.DataFrame(
    zip(money, honey, ltrs, YRMO, org), columns=["money", "honey", "ltrs", "YRMO", "org"]
)

YRMOs = sorted(set(df["YRMO"]))

pivot = df.pivot_table(
    values=["money", "honey"],
    index="ltrs",
    columns=["YRMO"],
    aggfunc={"money": np.sum, "honey": np.sum},
    margins=True,
    margins_name="Total",
)
pivot = pivot.drop("Total", axis=1, level=1)
pivot = pivot.fillna(0)

pivot["Var 1"] = pivot["money"][max(YRMOs)] - pivot["money"][min(YRMOs)]
pivot["Var 2"] = pivot["honey"][max(YRMOs)] - pivot["honey"][min(YRMOs)]

def color(val):
    global color
    if val[0] == '$' and float(val[1:].replace(",", "")) >1000:
        color = 'red'
    else:
        color = 'green'
    return f'color: {color}'

locale.setlocale(locale.LC_ALL, "us_US.UTF-8")

pivot = pivot.applymap(lambda x: locale.currency(val=x, grouping=True, symbol=True)).apply(lambda x: x.str.replace(pat=r"\.\d{2}",repl="", regex=True))

pivot = pivot.style.applymap(color, subset=['Var 1', 'Var 2'])

html_pivot = pivot.render()

运行报错的第二段代码

pivot2 = df[df['org'] == 'Jr'].pivot_table(
    values=["money", "honey"], 
    index="ltrs", 
    columns=['YRMO'], 
    aggfunc={"money": np.sum, "honey": np.sum},
    margins = True,
    margins_name = 'Total'
)

pivot2 = pivot2.drop("Total", axis=1, level=1)
pivot2 = pivot2.fillna(0)


pivot2["Var 1"] = pivot2["money"][max(YRMOs)] - pivot2["money"][min(YRMOs)]
pivot2["Var 2"] = pivot2["honey"][max(YRMOs)] - pivot2["honey"][min(YRMOs)]

pivot2 = pivot2.applymap(lambda x: locale.currency(val=x, grouping=True, symbol=True)).apply(lambda x: x.str.replace(pat=r"\.\d{2}",repl="", regex=True))


pivot2 = pivot2.style.applymap(color, subset=['Var 1', 'Var 2'])

html_pivot = pivot2.render()

问题原因

核心bug在color函数内的global color声明:

  • 第一次调用pivot.style.applymap(color)时,这个全局声明会将原本是函数类型的color覆盖成字符串类型('red'或'green')。
  • 第二次调用applymap(color)时,color已经是字符串,不再是可调用的函数,因此触发TypeError。

解决办法

删除color函数中的global color声明,改用局部变量存储颜色值,避免覆盖函数本身:

def color(val):
    # 移除global声明,使用局部变量
    if val[0] == '$' and float(val[1:].replace(",", "")) > 1000:
        color_val = 'red'
    else:
        color_val = 'green'
    return f'color: {color_val}'

修正后的完整代码

import numpy as np
import pandas as pd
import locale


money = [10000000, 2200000000, 10241100000.4521, 20224400000.75895]
honey = [30.6427984591421, 9584.28792256921, 37008.6603, 211200.2304295]
ltrs = ["a", "b", "a", "c"]
YRMO = ["202211", "202210", "202211", "202210"]
org = ['Main','Main', 'Jr', 'Jr']
df = pd.DataFrame(
    zip(money, honey, ltrs, YRMO, org), columns=["money", "honey", "ltrs", "YRMO", "org"]
)

YRMOs = sorted(set(df["YRMO"]))

# 第一段表格逻辑
pivot = df.pivot_table(
    values=["money", "honey"],
    index="ltrs",
    columns=["YRMO"],
    aggfunc={"money": np.sum, "honey": np.sum},
    margins=True,
    margins_name="Total",
)
pivot = pivot.drop("Total", axis=1, level=1)
pivot = pivot.fillna(0)

pivot["Var 1"] = pivot["money"][max(YRMOs)] - pivot["money"][min(YRMOs)]
pivot["Var 2"] = pivot["honey"][max(YRMOs)] - pivot["honey"][min(YRMOs)]

# 修正后的color函数
def color(val):
    if val[0] == '$' and float(val[1:].replace(",", "")) > 1000:
        color_val = 'red'
    else:
        color_val = 'green'
    return f'color: {color_val}'

locale.setlocale(locale.LC_ALL, "us_US.UTF-8")

pivot = pivot.applymap(lambda x: locale.currency(val=x, grouping=True, symbol=True)).apply(lambda x: x.str.replace(pat=r"\.\d{2}",repl="", regex=True))
pivot = pivot.style.applymap(color, subset=['Var 1', 'Var 2'])
html_pivot = pivot.render()

# 第二段表格逻辑(现在可正常运行)
pivot2 = df[df['org'] == 'Jr'].pivot_table(
    values=["money", "honey"], 
    index="ltrs", 
    columns=['YRMO'], 
    aggfunc={"money": np.sum, "honey": np.sum},
    margins = True,
    margins_name = 'Total'
)

pivot2 = pivot2.drop("Total", axis=1, level=1)
pivot2 = pivot2.fillna(0)

pivot2["Var 1"] = pivot2["money"][max(YRMOs)] - pivot2["money"][min(YRMOs)]
pivot2["Var 2"] = pivot2["honey"][max(YRMOs)] - pivot2["honey"][min(YRMOs)]

pivot2 = pivot2.applymap(lambda x: locale.currency(val=x, grouping=True, symbol=True)).apply(lambda x: x.str.replace(pat=r"\.\d{2}",repl="", regex=True))
pivot2 = pivot2.style.applymap(color, subset=['Var 1', 'Var 2'])
html_pivot2 = pivot2.render()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 16:37:19