遍历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
相关产品推荐
相关产品推荐

