如何将数字舍入到选定的整数

时间:2016-06-17 09:26:29

标签: python numpy rounding

在丹麦,我们有一个奇怪的评分系统如下。 [-3,00,02,4,7,10,12] 我们的任务是采用具有不同十进制数的向量,并将其四舍五入到最接近的有效等级。到目前为止,这是我们的代码。

import numpy as np

def roundGrade(grades):    
    if (-5<grades<-1.5):
        gradesRounded = -3
    elif (-1.5<=grades<1.5):
        gradesRounded = 00
    elif (1.5<=grades<3):
        gradesRounded = 2
    elif (3<=grades<5.5):
        gradesRounded = 4
    elif (5.5<=grades<8.5):
        gradesRounded = 7
    elif (8.5<=grades<11):
        gradesRounded = 10
    elif (11<=grades<15):
        gradesRounded = 12
    return gradesRounded

print(roundGrade(np.array[-2.1,6.3,8.9,9]))

我们的控制台似乎不喜欢这样并重新调整: TypeError:builtin_function_or_method'对象不可订阅

感谢所有帮助,如果您有更聪明的方法,欢迎您将我们放在我们的位置。

10 个答案:

答案 0 :(得分:25)

您收到该错误,因为在打印时,您使用的语法不正确:

print(roundGrade(np.array[-2.1,6.3,8.9,9]))

需要

print(roundGrade(np.array([-2.1,6.3,8.9,9])))

请注意额外的括号:np.array(<whatever>)

但是,这不会起作用,因为你的功能需要一个数字。幸运的是,numpy提供了一个可以解决这个问题的功能:

In [15]: roundGrade = np.vectorize(roundGrade)

In [16]: roundGrade(np.array([-2.1,6.3,8.9,9]))
Out[16]: array([-3,  7, 10, 10])

http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.vectorize.html

答案 1 :(得分:18)

您可以简单地将每个年级的最小距离带到每个年级组,就像这样。这假设您实际上想要从您的成绩组中舍入到最接近的成绩,而您当前的代码并不完全正确。

grade_groups = [-3,0,2,4,7,10,12]
sample_grades = [-2.1,6.3,8.9,9]
grouped = [min(grade_groups,key=lambda x:abs(grade-x)) for grade in sample_grades]
print(grouped)

<强>输出

[-3, 7, 10, 10]

请注意,即使在修复错误后,您的方法仍然有效,因为roundGrade需要一个数字作为参数。 As shown by juanapa你可以对你的功能进行矢量化。

答案 2 :(得分:2)

我会通过计算它最接近的有效等级并返回那个有效等级:

{{1}}

这当然只允许您一次传递一个等级,但是您可以在函数外部或在其内部循环遍历您的小数组数组以使其与数组兼容。

答案 3 :(得分:2)

def roundGrade(grade):
    d = {x:abs(x - grade) for x in [-3,00,02,4,7,10,12]}
    return min(d, key=d.get)
print list(map(roundGrade, [-2.1, 6.3, 8.9, 9]))

效率较低(我认为)但是代码要小得多 它创建了一个字典,其中键是圆形等级,值是圆形等级和给定等级之间的差值 然后它找到最小值(最小差值)并返回键(舍入值
然后它只使用map将此函数应用于列表中的每个项目

答案 4 :(得分:2)

我认为您可以仅使用列表在单行中执行此操作:

l = [-2.1,6.3,8.9,9]
b = [-3,0,02,4,7,10,12]

a = [b[min(enumerate([abs(j - item) for j in b]), key=lambda p:p[1])[0]] for item in l]
>>> [-3, 7, 10, 10]

您可以将其分解为:

min(enumerate([abs(j - item) for j in b]), key=lambda p:p[1])[0]  # Find the index of the nearest grade boundary
[b[...] for item in l]  # Get the associated grade boundary for all the items in the original list

答案 5 :(得分:1)

好吧,即使没有测试你的代码,我也可以看到一些问题。

你的函数roundGrade接受一个数字并返回一个数字,但是当你调用它时,你会为它提供一个数组。假设你的缩进是正确的并且调用不在函数内部,我会做类似的事情:

def roundGrade(grades):

    if (-5<grades<-1.5):
        gradesRounded = -3
    elif (-1.5<=grades<1.5):
        gradesRounded = 00
    elif (1.5<=grades<3):
        gradesRounded = 2
    elif (3<=grades<5.5):
        gradesRounded = 4
    elif (5.5<=grades<8.5):
        gradesRounded = 7
    elif (8.5<=grades<11):
        gradesRounded = 10
    elif (11<=grades<15):
        gradesRounded = 12
    return gradesRounded

#print(roundGrade(np.array[-2.1,6.3,8.9,9]))
# Here, I assume you want to round each of the grades in the array. If I'm wrong, comment, please!

for i in [-2.1, 6.3, 8.9, 9]:
    print roundGrade(i)

调用方法并提供数组是不行的,而使用每个元素调用该方法是可以的,因为该方法应该接收数字而不是数组。

答案 6 :(得分:1)

我将如何做到这一点:

def roundGrade(grades_in):
    grades_out = []
    for grades in grades_in:
        if grades < -5 or grades > 15:
            gradesRounded = '??'
            print('Grade input out of range ({:})!'.format(grades))
        if (-5<grades<-1.5):
            gradesRounded = '-3'
        elif (-1.5<=grades<1.5):
            gradesRounded = '00'
        elif (1.5<=grades<3):
            gradesRounded = '2'
        elif (3<=grades<5.5):
            gradesRounded = '4'
        elif (5.5<=grades<8.5):
            gradesRounded = '7'
        elif (8.5<=grades<11):
            gradesRounded = '10'
        elif (11<=grades<15):
            gradesRounded = '12'
        grades_out.append(gradesRounded)
    return grades_out

 grades_in = [-7, -2.1, 0.1, 6.3, 8.9, 9]
 print(roundGrade(grades_in))  #prints: ['??', '-3', '00', '7', '10', '10']

取一个列表并返回一个。处理超出范围的输入和返回的列表项是字符串而不是整数来添加那些花哨的&#34; 00&#34;而不是&#34; 0&#34;。

答案 7 :(得分:1)

由于行

中的额外括号,您收到该错误
print(roundGrade(np.array([-2.1,6.3,8.9,9])))

应该是

print(roundGrade(np.array[-2.1,6.3,8.9,9]))

答案 8 :(得分:0)

至于异常,numpy数组是一个函数,需要用()调用 所以你的方法调用应该是:

QGraphicsScene

而不是:

print(roundGrade(np.array([-2.1,6.3,8.9,9])))

至于功能本身,要么使用 grades.any() grades.all()来测试整个元素,否则未定义比较。

答案 9 :(得分:0)

我建议在这里使用numpy.digitize,因为它可以使您轻松地向量化此操作。

设置

bins = np.array([-5, -1.5, 1.5, 3, 5.5, 8.5, 11, 15])
outputs = np.array([-3,  0,  2,  4,  7, 10, 12])

grades = np.array([-2.1,  6.3,  8.9,  9. ])

使用 numpy.digitize

outputs[np.digitize(grades, bins)-1]

array([-3,  7, 10, 10])

即使其他答案显示了如何使用np.vectorizedigitize仍将在对值进行装箱时为您带来很大的性能提升:

_v_round_grade = np.vectorize(roundGrade)
grades = np.random.randint(-4, 14, 10000)

In [496]: %timeit _v_round_grade(grades)
5.64 ms ± 24.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [497]: %timeit outputs[np.digitize(grades, bins)-1]
210 µs ± 567 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

验证

>>> np.array_equal(_v_round_grade(grades), outputs[np.digitize(grades, bins)-1])
True

使用此内置digitize函数比简单地向量化自己的函数要快 25倍