Python pandas:如何将自定义函数应用到DataFrame指定行及NameError解决
Python DataFrame练习题报错与实现问题排查
题目要求
- 计算目标DataFrame中
Avg_User_IMDB、Avg_User_Rtn_Tom两个变量的均值,分别存储为mean_1和mean_2 - 编写名为
qualify()的函数,入参为单条数据行,评级规则如下:- 同时满足两个条件时评级为
excellent:行内Bond_Actor取值为Sean Connery或Daniel Craig,且该行Avg_User_IMDB大于mean_1、Avg_User_Rtn_Tom大于mean_2 - 其余所有情况评级为
regular
- 同时满足两个条件时评级为
现有运行代码
mean_1 = dfbond['Avg_User_IMDB'].mean() mean_2 = dfbond['Avg_User_Rtn_Tom'].mean() print(mean_1) print(mean_2) is_SirSeanConery = dfbond['Bond_Actor'] == 'Sir Sean Connery' is_DanielCraig = dfbond['Bond_Actor'] == 'Daniel Craig' tam = int(input('How many rows are you gona use: ')) if tam < 1: print('¡DOESN´T HELP!') else: row = [] for i in range(tam): print ('Write the rows', str(i + 1) + ": ",end="") ol = int(input()) row.append(ol) print('The rows are: ', row) def qualify(row): r = dfbond.iloc[row] final = r[['Bond_Actor','Avg_User_IMDB','Avg_User_Rtn_Tom']] for i in final: if dfbond['Bond_Actor'] == is_SirSeanConery or is_DanielCraig: if dfbond['Avg_User_IMDB'] > mean_1 and dfbond['Avg_User_Rtn_Tom'] > mean_2: print('Excellent') else: print('Regular') else: print('Regular') print(final)
控制台报错信息
NameError Traceback (most recent call last) <ipython-input-57-a16ac904974e> in <module> 11 print('Regular') 12 ---> 13 print(final) NameError: name 'final' is not defined
问题根因
- 直接触发报错的原因:
final是定义在qualify()函数内部的局部变量,函数作用域外的print(final)无法访问这个变量,因此抛出未定义错误。 - 即使修复上述报错,代码仍存在多处逻辑偏差,无法满足题目要求:
- 不符合函数入参规则:题目要求
qualify()接收单条数据行作为入参,但当前代码传入的是用户手动输入的行索引,在函数内部重新通过dfbond.iloc[row]取数,和题目要求完全不匹配 - 演员判断逻辑错误:代码直接调用整列
dfbond['Bond_Actor']和提前生成的布尔Series做比较,没有针对当前处理的单条记录的演员值做判断 - 条件判断写法错误:
dfbond['Bond_Actor'] == is_SirSeanConery or is_DanielCraig是对整列布尔值做逻辑运算,无法实现“单条记录的演员为两个选项之一”的判断 - 冗余输入逻辑:题目没有要求让用户手动输入待处理的行索引,这部分是额外添加的无效代码。
- 不符合函数入参规则:题目要求
可正常运行的参考实现
# 1. 计算两个字段的均值 mean_1 = dfbond['Avg_User_IMDB'].mean() mean_2 = dfbond['Avg_User_Rtn_Tom'].mean() print(f"Avg_User_IMDB均值:{mean_1:.2f},Avg_User_Rtn_Tom均值:{mean_2:.2f}") # 2. 定义符合题目要求的qualify函数 def qualify(single_row): # 从传入的单条数据行中提取需要判断的字段值 actor = single_row['Bond_Actor'] imdb_val = single_row['Avg_User_IMDB'] tomato_val = single_row['Avg_User_Rtn_Tom'] # 按规则判断评级 # 注:如果数据中Sean Connery的存储值为带头衔的"Sir Sean Connery",替换列表中对应值即可 if (actor in ['Sean Connery', 'Daniel Craig']) and (imdb_val > mean_1) and (tomato_val > mean_2): return 'excellent' else: return 'regular' # 测试:对DataFrame所有行应用评级函数,新增评级列 dfbond['movie_rating'] = dfbond.apply(qualify, axis=1) # 输出处理结果 print(dfbond[['Film', 'Bond_Actor', 'Avg_User_IMDB', 'Avg_User_Rtn_Tom', 'movie_rating']])
内容的提问来源于stack exchange,提问作者José Luis Berrospe
相关产品推荐
相关产品推荐

