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

遍历Pandas透视表计算新列时遇NameError问题求助

解决Pandas条件赋值中的变量提前求值问题

最直接的解决方案:跳过字典,直接用布尔条件定位

你不需要用字典来实现这个需求,直接通过loc结合布尔条件就能完成赋值,既简单又高效:

import pandas as pd

# 先给新列初始化空值
sales_pivot['2019_udc'] = ''
# 精准定位符合条件的行:2018年有消费(假设消费>0代表有消费)且2019年消费为0
sales_pivot.loc[(sales_pivot[2018] > 0) & (sales_pivot[2019] == 0), '2019_udc'] = 'Churn'

如果之后要对2020、2021等年份复用相同逻辑,把逻辑封装成函数就行,避免重复代码:

def mark_churn(df, target_year):
    prev_year = target_year - 1
    new_col = f'{target_year}_udc'
    df[new_col] = ''
    df.loc[(df[prev_year] > 0) & (df[target_year] == 0), new_col] = 'Churn'

# 给2019年打标签
mark_churn(sales_pivot, 2019)
# 给2020年打标签
mark_churn(sales_pivot, 2020)

如果一定要用字典实现延迟求值

如果坚持要用字典来管理不同年份的逻辑,问题出在你直接把year变量写进字典的条件里,Python会立即尝试解析year导致报错。解决办法是把条件包装成可调用对象(比如lambda),让字典存储逻辑而非直接计算结果:

# 字典里存的是接收DataFrame的lambda,不会立即求值
churn_logic = {
    2019: lambda df: (df[2018] > 0) & (df[2019] == 0)
}

# 遍历字典,给对应年份的列赋值
for year, condition in churn_logic.items():
    col_name = f'{year}_udc'
    # 用loc结合条件直接赋值,比apply高效
    sales_pivot[col_name] = ''
    sales_pivot.loc[condition(sales_pivot), col_name] = 'Churn'

注意:这种方法本质还是用loc,只是把条件存在字典里,避免了变量提前求值的问题。如果数据量较大,优先用第一种方法,apply的性能远不如直接的布尔索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:51:26