如何将数字四舍五入为选定的整数
How to round a number to a chosen integer
在丹麦,我们有一个奇怪的评分系统,如下所示。 [-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]))
我们的控制台似乎不喜欢这样并重新调整:
类型错误:builtin_function_or_method' 对象不可订阅
感谢所有帮助,如果您有更聪明的方法,欢迎将我们放在我们的位置。
好吧,即使没有测试你的代码,我也能看出一些问题。
您的函数 roundGrade
接受一个数字,returns 接受一个数字,但是当您调用它时,您向它提供了一个数组。假设你的缩进没问题并且调用不在函数内部,我会做这样的事情:
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)
调用该方法并提供一个数组是不行的,但是用每个元素调用该方法是可以的,因为该方法应该接收一个数字而不是一个数组。
关于异常,numpy数组是一个函数,需要用()调用
所以你的方法调用应该是这样的:
print(roundGrade(np.array([-2.1,6.3,8.9,9])))
而不是:
print(roundGrade(np.array[-2.1,6.3,8.9,9]))
至于函数本身,要么使用
grades.any()或grades.all()测试整个元素,否则比较不定义。
我就是这样做的:
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']
获取列表,returns获取列表。处理超出范围的输入,返回的列表项是字符串而不是整数,以添加花哨的“00”而不是“0”。
您收到该错误是因为您在打印时使用了不正确的语法:
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
我会通过计算它最接近哪个有效等级并返回那个有效等级来四舍五入:
import numpy as np
def roundGrade(grade):
validGrades = np.array([-3,0,2,4,7,10,12])
return validGrades[np.argmin((grade-validGrades)**2)]
这当然只允许您一次通过一个成绩,但您可以在函数外部或函数内部循环遍历小数数组以使其与数组兼容。
您可以简单地取从每个年级到每个年级组的最小距离,就像这样。这假设您实际上想要从您的年级组四舍五入到最接近的年级,而您当前的代码并没有完全做到这一点。
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
需要一个数字作为参数。 你可以向量化你的函数。
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]))
效率较低(我认为)但代码要小得多
它创建了一个字典,其中键是一个圆形等级,值是圆形等级和给定等级之间的差异
然后它找到最小值(最小差异)和 returns 键(舍入值
然后它只使用 map
将此函数应用于列表中的每个项目
我认为您可以仅使用列表在一行中完成此操作:
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
您收到该错误是因为行中有额外的括号
print(roundGrade(np.array([-2.1,6.3,8.9,9])))
应该是
print(roundGrade(np.array[-2.1,6.3,8.9,9]))
我建议在这里使用 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.vectorize
,digitize
仍然会在合并值时为您提供较大的性能提升:
_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 倍。
在丹麦,我们有一个奇怪的评分系统,如下所示。 [-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]))
我们的控制台似乎不喜欢这样并重新调整: 类型错误:builtin_function_or_method' 对象不可订阅
感谢所有帮助,如果您有更聪明的方法,欢迎将我们放在我们的位置。
好吧,即使没有测试你的代码,我也能看出一些问题。
您的函数 roundGrade
接受一个数字,returns 接受一个数字,但是当您调用它时,您向它提供了一个数组。假设你的缩进没问题并且调用不在函数内部,我会做这样的事情:
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)
调用该方法并提供一个数组是不行的,但是用每个元素调用该方法是可以的,因为该方法应该接收一个数字而不是一个数组。
关于异常,numpy数组是一个函数,需要用()调用 所以你的方法调用应该是这样的:
print(roundGrade(np.array([-2.1,6.3,8.9,9])))
而不是:
print(roundGrade(np.array[-2.1,6.3,8.9,9]))
至于函数本身,要么使用 grades.any()或grades.all()测试整个元素,否则比较不定义。
我就是这样做的:
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']
获取列表,returns获取列表。处理超出范围的输入,返回的列表项是字符串而不是整数,以添加花哨的“00”而不是“0”。
您收到该错误是因为您在打印时使用了不正确的语法:
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
我会通过计算它最接近哪个有效等级并返回那个有效等级来四舍五入:
import numpy as np
def roundGrade(grade):
validGrades = np.array([-3,0,2,4,7,10,12])
return validGrades[np.argmin((grade-validGrades)**2)]
这当然只允许您一次通过一个成绩,但您可以在函数外部或函数内部循环遍历小数数组以使其与数组兼容。
您可以简单地取从每个年级到每个年级组的最小距离,就像这样。这假设您实际上想要从您的年级组四舍五入到最接近的年级,而您当前的代码并没有完全做到这一点。
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
需要一个数字作为参数。
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]))
效率较低(我认为)但代码要小得多
它创建了一个字典,其中键是一个圆形等级,值是圆形等级和给定等级之间的差异
然后它找到最小值(最小差异)和 returns 键(舍入值
然后它只使用 map
将此函数应用于列表中的每个项目
我认为您可以仅使用列表在一行中完成此操作:
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
您收到该错误是因为行中有额外的括号
print(roundGrade(np.array([-2.1,6.3,8.9,9])))
应该是
print(roundGrade(np.array[-2.1,6.3,8.9,9]))
我建议在这里使用 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.vectorize
,digitize
仍然会在合并值时为您提供较大的性能提升:
_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 倍。