2016-06-21 25 views
1

我有一个数据框,DF,类似于下面的。将字母等级转换为GPA:我的代码出了什么问题?

ID  SUBJ   GRADE 

1 Amer Natl Govt  A 
2 Princ Of Macroecon B 
3 General Biology  B 
4 Concept Of Chem  C 
5 General Chem  C 

我只是想将字母等级(GRADE)转换为成绩平均值。

我写了下面的代码,它总是返回所有行的异常2.3,就好像我的元组列表中的字母的数据类型与我的数据框中的类型不同,但它们都是字符串。有人能告诉我我的代码有问题吗?谢谢。

def getGradePoint(row): 

    grades = [('A+', 4.0), ('A', 4.0), ('A-', 3.7), ('B+',3.3), ('B',3.0), ('B-',2.7), ('C+',2.3), ('C',2.0),\ 
      ('C-',1.7),('D+',1.3),('D',1.0),('D-',0.7),('F',0.0)] 
    for i in range(len(grades)): 
     if row == grades[i][0]: 
      return grades[i][1] 
     else: 
      return 2.3 

df['GRADE_PT'] = df['GRADE'].apply(getGradePoint) 

ID  SUBJ   GRADE GPA 

1 Amer Natl Govt  A  2.3 
2 Princ Of Macroecon B  2.3 
3 General Biology  B  2.3 
4 Concept Of Chem  C  2.3 
5 General Chem  C  2.3 

回答

4

问题是,您的循环将始终在第一次迭代中返回结果。在第一次迭代,你('A+', 4.0)的元组中,if声明False因为档次不A+,所以else声明被评估并返回2.3

相反,返回2.3循环完成后,才:

def getGradePoint(row): 
    grades = [('A+', 4.0), ('A', 4.0), ('A-', 3.7), ('B+',3.3), ('B',3.0), ('B-',2.7), ('C+',2.3), ('C',2.0), \ 
      ('C-',1.7),('D+',1.3),('D',1.0),('D-',0.7),('F',0.0)] 
    for i in range(len(grades)): 
     if row == grades[i][0]: 
      return grades[i][1] 

    return 2.3 

然而,如前所述,它更容易只需使用一本字典。使用您现有的grades结构:

grades = [('A+', 4.0), ('A', 4.0), ('A-', 3.7), ('B+',3.3), ('B',3.0), ('B-',2.7), ('C+',2.3), ('C',2.0),\ 
      ('C-',1.7),('D+',1.3),('D',1.0),('D-',0.7),('F',0.0)] 
df['GRADE_PT'] = df['GRADE'].map(dict(grades)) 
2

使用字典来代替。

my_grad={'A': 4.0, 'B' : 3.0} 

df['new_grades']=df.GRADE.map(my_grad) 
1

我强烈建议使用python字典来存储等级值。这将消除循环的需要。至于为什么它不起作用,请考虑一下你的循环在做什么。对于每个年级,它首先检查该年级是否为'A +',因为这是成绩中的第一个入围。然后,因为它不是,它直接到else语句并返回2.3。尝试使用else语句只是打印某些内容或完全删除else语句。只要确保你摆脱了else中的return语句。

相关问题