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

Python自定义函数问题:从df1、df2获取用户最高训练等级无输出

问题排查与解决建议

代码核心问题

  1. 缩进错误导致逻辑失效:updateTraining方法中,等级判断的if/elif块完全没有缩进,属于类的顶层代码,调用方法时根本不会执行。也就是说,你调用updateTraining时只会执行最开始的if hasattr逻辑,后续的等级判断完全没运行,导致用户的等级属性可能没被正确设置,甚至根本没创建。
  2. 属性与传参不匹配:
    • 类的__init__方法接收的第四个参数是status,但实例化时传入的是df1['Title'],后续打印却用了person.title,但类里根本没定义self.title属性,只有self.status,这里存在潜在报错风险。
    • 调用updateTraining时传入的是dfPerson['Item ID'],但问题描述中你需要的是训练等级,如果Item ID不是Lev_1/Lev_2/Lev_3这类等级值,后续的等级判断逻辑完全不生效,自然不会生成level和trainingDate属性,最后hasattr(person, 'level')为False,不会触发打印。
  3. 逻辑冗余冲突:最开始的if hasattr(self, 'level') == False逻辑和后面的等级判断重复,就算缩进正确,也会导致先有低等级的用户后续完成高等级时,因已存在level属性跳过初始判断,但后续高等级覆盖逻辑本应执行,却因缩进错误没运行。

修复后的代码

修正缩进、属性匹配和传参问题,优化逻辑:

class Colleague:
    def __init__(self, user_id, first_name, last_name, title):
        self.user_id = user_id
        self.first_name = first_name
        self.last_name = last_name
        self.title = title

    def update_training(self, level, date):
        # 定义等级优先级:Lev_3 > Lev_2 > Lev_1
        level_priority = {'Lev_1': 1, 'Lev_2': 2, 'Lev_3': 3}
        # 无等级时直接设置
        if not hasattr(self, 'level'):
            self.level = level
            self.training_date = date
        else:
            # 比较新等级与当前等级的优先级,只保留更高等级
            current_prio = level_priority.get(self.level, 0)
            new_prio = level_priority.get(level, 0)
            if new_prio > current_prio:
                self.level = level
                self.training_date = date

# 实例化所有用户
colleague_list = []
for idx in df1.index:
    colleague_list.append(Colleague(
        df1['User Sys ID'][idx],
        df1['First Name'][idx],
        df1['Last Name'][idx],
        df1['Title'][idx]
    ))

# 遍历更新训练信息
for person in colleague_list:
    person_records = df2[df2['User Sys ID'] == person.user_id]
    # 注意:替换'Training Level'为df2中实际的训练等级列名
    for _, record in person_records.iterrows():
        person.update_training(record['Training Level'], record['Completion Date'])
    # 打印有训练记录的用户信息
    if hasattr(person, 'level'):
        print(person.user_id, person.first_name, person.title, person.level, person.training_date)

更高效的Pandas原生实现

用类循环的方式效率极低,尤其是数据量大时,直接用Pandas分组排序合并操作更简洁:

# 1. 给训练等级设置优先级,用于排序
df2['level_priority'] = df2['Training Level'].map({'Lev_1':1, 'Lev_2':2, 'Lev_3':3})
# 2. 按用户分组,取等级最高的记录;同等级取最新日期的记录
top_training = df2.sort_values(
    by=['User Sys ID', 'level_priority', 'Completion Date'],
    ascending=[True, False, False]
).drop_duplicates(subset=['User Sys ID'], keep='first')
# 3. 合并用户表与最高训练记录,保留需要的列
result = df1.merge(
    top_training[['User Sys ID', 'Training Level', 'Completion Date']],
    on='User Sys ID',
    how='left'
)
# 输出结果
print(result)

注意:

  • 替换代码中的Training Level为df2中实际的训练等级列名。
  • 如果同一用户同一等级有多个完成日期,上述代码会保留最新的日期记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:35:04