2016-06-17 24 views
16

W Danii mamy dziwny system oceniania, który wygląda następująco. [-3,00,02,4,7,10,12] Naszym zadaniem jest pobranie wektora z różnymi liczbami dziesiętnymi i zaokrąglenie go do najbliższej prawidłowej oceny. Oto nasz kod do tej pory.Jak zaokrąglić liczbę do wybranej liczby całkowitej

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])) 

Nasza konsola wydaje się nie podoba i retuns: TypeError: builtin_function_or_method”obiekt nie jest subscriptable

Każda pomoc jest mile widziana, a jeśli masz inteligentniejsze metody zapraszamy umieścić nas u nas.

+3

tam absolutnie nie ma potrzeby dla numpy tutaj. –

+1

@ Ev.Kounis Zakładam, że numpy jest używany z dobrego powodu i że jest to po prostu zabawny przykład, lub zaproponowałbym po prostu użycie listy z wbudowaną funkcją 'map'. –

Odpowiedz

18

Możesz po prostu wziąć minimalną odległość od każdej klasy do każdej grupy ocen, tak jak. Zakłada to, że faktycznie chcesz zaokrąglić do najbliższej klasy z twojej grupy ocen, której twój aktualny kod nie robi dokładnie.

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) 

Wyjścia:

[-3, 7, 10, 10] 

pamiętać, że nawet po zamontowaniu swój błąd twoje podejście nie będzie jeszcze działać, ponieważ roundGrade spodziewa jeden numer jako parametr. As shown by juanapa możesz wektoryzować swoją funkcję.

1

Cóż, nawet bez testowania kodu, widzę tutaj pewne problemy.

Twoja funkcja, roundGrade, pobiera liczbę i zwraca liczbę, ale po jej wywołaniu podajesz do niej tablicę. Zakładając, że wcięcie jest ok, a połączenie nie jest wewnątrz funkcji, chciałbym zrobić coś takiego:

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) 

wywołanie metody i zapewniając tablicę nie jest ok, natomiast wywołanie tej metody z każdym z elementów jest ok , ponieważ metoda ma otrzymać liczbę, a nie tablicę.

0

Co do wyjątku numpy tablicy to funkcja, i trzeba być wywołana z() Więc wywołanie metody powinno być tak:

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

a nie:

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

As dla samej funkcji albo użyj grades.any() lub grades.all(), aby przetestować całe elementy, w przeciwnym razie porównanie nie zostanie zdefiniowane.

1

Tak chciałbym to zrobić:

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'] 

przyjmuje listę i zwraca jeden. Uchwyty poza zakresem wejściowym i zwrócone elementy listy są ciągami zamiast liczb całkowitych, aby dodać tę wymyślną "00", a nie "0".

25

Otrzymujesz ten błąd, ponieważ podczas drukowania, używasz nieprawidłowej składni:

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

musi być

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

Wskazówki dodatkowe nawiasy: np.array(<whatever>)

to jednak nie zadziała, ponieważ twoja funkcja oczekuje jednej liczby.Na szczęście numpy zapewnia funkcję, która może naprawić to dla ciebie:

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

3

bym runda obliczając których ważny gatunek to jest najbliższa i powracający że jeden:

import numpy as np 
def roundGrade(grade): 
    validGrades = np.array([-3,0,2,4,7,10,12]) 
    return validGrades[np.argmin((grade-validGrades)**2)] 

ten Oczywiście pozwala tylko na zaliczenie pojedynczej oceny na raz, ale możesz po prostu zapętlić swoją tablicę cyfr po przecinku, albo poza funkcją, albo wewnątrz, aby była kompatybilna z tablicą.

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])) 

Jest mniej skuteczny (myślę), ale jest znacznie mniejszy kod
Tworzy słownika gdzie kluczem jest okrągła grade a wartość jest różnica pomiędzy kolejki klasy i danego gatunku
Następnie stwierdzi wartość minimalną (najmniejsza różnica) i zwraca klucz (wartość zaokrąglona
Wtedy to właśnie używa map zastosować tę funkcję na każdej pozycji na liście

2

myślę, że można to zrobić w jednym liniowiec używający tylko list:

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] 

Można to rozbić jak:

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 
1

Otrzymujesz ten błąd ze względu na dodatkowe nawiasie w linii

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

jest powinny być

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