如何从矩阵中的行中删除最小值-

How to remove minimum value from row in a matrix-

所以我们的任务是创建一个函数来获取输入成绩〜(一个 N × M 矩阵,其中包含在 M 个不同作业中给予 N 个学生的 7 级等级的成绩。),并计算 gradesFinal(A长度为 n 的向量,包含 N 个学生中每个学生的最终成绩。)。

对于每个学生,最终成绩必须按以下方式计算:

  1. 如果只有一个作业(M = 1),最终成绩等于该作业的成绩。

  2. 如果有两个或更多作业 (M > 1),则最低分数将被丢弃。最终成绩计算为 M − 1 个最高成绩的平均值,四舍五入到 刻度上最近的等级(使用函数 roundGrade)。

  3. 不管上述情况如何,如果学生在一项或多项作业中获得-3 分,则最终成绩必须始终为-3。

我在下面插入了我的 roundGrade 函数,但是当我尝试 运行 一个矩阵时,我收到了。 “TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'”。这意味着我可能完全误解了一些东西。

import numpy as np
def computeFinalGrades(grades):
    if len(grades)==1:
    gradesFinal = grades
elif len(grades)>=2:
    trimmed = grades.remove(min(grades))
    finalgrade = np.mean(trimmed)
    gradesFinal = roundGrade(finalgrade)
elif grades[grades==-3]:
    gradesFinal= -3
    return gradesFinal

def roundGrade(grades):
   grade_groups = [-3,0,2,4,7,10,12]
   gradesRounded = [min(grade_groups,key=lambda x:abs(grade-x)) for grade in     grades]
   return gradesRounded

感谢您的帮助,欢迎向我展示更聪明的方法。

grades.remove(min(grades)) 没有 return 任何东西。所以 trimmedNone。此外,您的 roundGrade 函数是错误的,因为您将一个数字传递给 roundGrade,并试图在 gradesRounded = [min(grade_groups,key=lambda x:abs(grade-x)) for grade in grades] 中迭代。

下面的代码一定能帮到您。

def computeFinalGrade(g_vector):
    if -3 in g_vector: # Irrespective of the length of the g_vector
        return -3
    if len(g_vector) == 1:
        return g_vector[0]
    g_vector.remove(min(g_vector))
    return roundGrade(sum(g_vector)/float(len(g_vector)))

def roundGrade(meanGrade):
   gradeGroups = [-3,0,2,4,7,10,12]
   return min(gradeGroups,key=lambda x:abs(meanGrade-x))

gradesFinal = []
grades = [
    [1, 2, 3, 4],
    [1, -3, 2, 4],
    [5],
    [9, 6, 2, 1]
]

for grade_vector in grades: # grades is a N*M matrix [[1, 2, 3 ... M], [1, 2, 3 ... M], ... N times]
    gradesFinal.append(computeFinalGrade(grade_vector))
    # >>>  gradesFinal
    #      [2, -3, 5, 7]

原代码大概有5个地方需要改动:缩进,list.removeif/elif顺序,检查值是否存在的方式for 在列表中并在 roundGrade() 函数中传递列表。

1.缩进

首先,您的缩进不正确。 python 解释器考虑了缩进,所以这很重要。在每个 if 语句之后,您应该缩进该特定条件的代码块。除此之外,您还应该确保您的 if 和 elif 处于同一缩进级别。所以它应该看起来像这样。

import numpy as np
def computeFinalGrades(grades):
    if len(grades)==1:
        gradesFinal = grades
    elif len(grades)>=2:
        trimmed = grades.remove(min(grades))
        finalgrade = np.mean(trimmed)
        gradesFinal = roundGrade(finalgrade)
    elif grades[grades==-3]:
        gradesFinal= -3
    return gradesFinal

def roundGrade(grades):
   grade_groups = [-3,0,2,4,7,10,12]
   gradesRounded = [min(grade_groups,key=lambda x:abs(grade-x)) for grade in     grades]
   return gradesRounded

2。 list.remove returns None

其次,假设您将列表传递给 computeFinalGrades,trimmed = grades.remove(min(grades)) 中的 grades.remove 就地修改了成绩列表并且 returns None。因此,当您在其上调用函数 roundGrade 时,您会得到 NoneType Error.

3。 if/elif 块的顺序

第三,if块的流程是错误的。考虑将数组 [1,2,3,4,5,-3] 传递给 computeFinalGrades([1,2,3,4,5,-3]) 的场景,然后 if 语句 if len(grades)==1 将为 return True 并且计算将停止那里。相反,您应该将 grades[grades==-3] 移动到顶部作为要评估的第一个语句,因为一旦该语句为真,-3 应该始终 returned.

4。检查列表中的值

第四,grades[grades==-3] 首先评估变量 grades 是否引用 -3,这又 returns false 因为 grades 始终是一个列表而不是整数 -3。在这一点上,你有 grades[False] 被视为等同于 grades[0] 因此你总是得到第一个结果。相反,pythonic 方法是使用 in 运算符。 IE。 elif -3 in grades:

5. roundGrade 尝试对不可迭代对象进行两次迭代

第五,gradesFinal = roundGrade(finalgrade) 不起作用,因为 finalgrade = np.mean(trimmed) 是一个数字。但是,您在这个数字上调用 roundGrade,然后在函数 roundGrade 中迭代这个数字 for grade in grades。当您尝试 min(grade_groups,key=lambda x:abs(grade-x)) 时会发生同样的错误。这是因为您在单个值上调用 min。如果你想最小化这个配对,更好的方法是 gradesRounded = [(grade,lambda x:abs(mean_grade-x)) for grade in grade_groups]。因此你应该知道你何时传入列表或变量。

我编辑了 roundGrade 以接受单个值,然后遍历您的成绩分组以创建一个包含绝对值差异的元组列表,然后是成绩分组中的成绩。然后我按升序对它进行排序,并简单地 return 第一个元组中的第二个值,即你在年级 table 中的成绩。请注意,如果 mean_grade 恰好位于 grade_groups.[=31= 中的两个相邻值之间,则总是 return 在 grade_groups 中使用较低等级的缺点]

综合起来,一种方法是:

import numpy as np

def computeFinalGrades(grades):
    if -3 in grades:
        print grades
        gradesFinal= -3
    elif len(grades)>=2:
        grades.remove(min(grades))
        finalgrade = np.mean(grades)
        gradesFinal = roundGrade(finalgrade)
    elif len(grades)==1:
        gradesFinal = grades
    return gradesFinal

def roundGrade(mean_grade):

    grade_groups = [-3,0,2,4,7,10,12]
    gradesRounded = [(abs(grade-mean_grade),grade)for grade in grade_groups]
    gradesRounded.sort()
    return gradesRounded[0][1]

这是一个直接作用于 NxM 二维数组的解决方案,而不是单独作用于每个向量,所以我假设所有学生的 M 都相同,并且缺失值(作业)设置为nanG 也可以是 1d,这意味着每个学生只有 1 个作业。

def grades(G):
    import numpy

    # return G directly if there is only 1 assignment (M=1)
    if len(G.shape) == 1 or G.shape[1] == 1:
        return G[:]

    # sort for easier calculation of mean
    SG = numpy.sort(G)

    # set all values to -3 if a -3 is found on any assignment of that student
    m3 = numpy.where(SG==-3)[0]
    SG[m3] = -3

    levels = numpy.array((-3, 0, 2, 4, 7, 10, 12))
    # take the mean of all assigments except the worst (index=0 of each student)
    MG = numpy.nanmean(SG[:,1:], axis=-1)

    # find the nearest grade in the list of levels, rounding down if two are equally close
    diffs = numpy.abs(MG[:,None] - levels)
    index = numpy.nanargmin(diffs, axis=-1)

    return levels[index]