如何将DataFrame成绩匹配循环代码改写为更高效的函数?
更高效的等级转分数实现方案
你的需求是把每个学生的等级列表转换成对应的分数列表,当前的嵌套循环+异常处理虽然可行,但在数据量增大时会有明显的性能瓶颈。我们可以通过字典映射和pandas向量化操作来优化,让代码更简洁、执行更快。
第一步:构建等级-分数的映射字典
首先把score DataFrame转换成字典,这样查找等级对应的分数是O(1)的时间复杂度,比每次用loc遍历DataFrame高效得多:
import pandas as pd # 假设你的score和students DataFrame已经创建 score_map = score.set_index('grade')['score'].to_dict()
第二步:快速转换等级列表为分数列表
利用pandas.Series.apply配合列表推导,结合字典的get方法(自动处理找不到的等级,返回默认值0),一行代码就能完成转换:
students['score'] = students['grades'].apply( lambda grades_list: [score_map.get(grade, 0) for grade in grades_list] )
效果验证
执行后你的students DataFrame会变成:
name grades score 0 Adam [A, B, A, F] [90, 80, 90, 0] 1 Jane [C, B, A, F] [70, 80, 90, 0]
为什么这个方案更高效?
- 字典查找替代循环遍历:原来的
score.loc[score['grade'] == grade]每次都会遍历整个scoreDataFrame,而字典的get方法是直接查找,速度提升明显 - 去掉异常处理:用
get方法的默认值参数替代try-except,代码更简洁,也避免了异常捕获的性能开销 - 向量化操作:
apply配合列表推导比纯Python嵌套循环更贴合pandas的设计,在数据量较大时优势更显著
超大数据集的进阶方案
如果你的数据集非常大(比如上万条学生记录),可以用完全的向量化操作进一步优化(避免Python层面的循环):
# 展开等级列表 exploded_students = students.explode('grades') # 关联分数,找不到的填充0 merged = exploded_students.merge(score, left_on='grades', right_on='grade', how='left').fillna({'score': 0}) # 重新聚合回列表 students['score'] = merged.groupby('name')['score'].agg(list)
这个方案完全利用pandas的内部向量化逻辑,性能会比apply更优,但代码稍长,适合超大规模数据场景。
内容的提问来源于stack exchange,提问作者John peter
相关产品推荐
相关产品推荐

