Próbowałem znormalizować zbiór liczb od -100 do 0 do zakresu 10-100 i miałem problemy tylko po to, aby zauważyć, że nawet bez żadnych zmiennych nie ocenia to w sposób, w jaki bym się tego spodziewał:
>>> (20-10) / (100-10)
0
Podział pływający też nie działa:
>>> float((20-10) / (100-10))
0.0
Jeśli dowolna strona podziału zostanie rzucona na pływak, zadziała:
>>> (20-10) / float((100-10))
0.1111111111111111
Każda strona w pierwszym przykładzie jest oceniana jako int, co oznacza, że ostateczna odpowiedź zostanie rzutowana na int. Ponieważ 0,111 to mniej niż 0,5, zaokrągla się do 0. Moim zdaniem nie jest przezroczysty, ale myślę, że tak właśnie jest.
Jakie jest wyjaśnienie?
python
math
python-2.x
Adam Nelson
źródło
źródło
Odpowiedzi:
Używasz języka Python 2.x, w którym podziały w liczbach całkowitych zostaną obcięte, zamiast stać się liczbą zmiennoprzecinkową.
>>> 1 / 2 0
Powinieneś zrobić z jednego z nich
float
:>>> float(10 - 20) / (100 - 10) -0.1111111111111111
lub
from __future__ import division
, który wymusza/
przyjęcie zachowania Pythona 3.x, które zawsze zwraca wartość zmiennoprzecinkową.>>> from __future__ import division >>> (10 - 20) / (100 - 10) -0.1111111111111111
źródło
from __future__ import division
, możesz uzyskać podział na stary styl C, używając dwóch ukośników (np.1 // 2
Spowoduje 0). Zobacz Pep 238 Changing the Division Operator__future__
. W obu Python 2 i 3//
odnosi się__floordiv__()
domyślnie.Jesteś wprowadzenie liczb całkowitych więc Python daje Ci plecy całkowitą :
>>> 10 / 90 0
Jeśli później rzucisz to na zmiennoprzecinkowe, zaokrąglenie zostanie już wykonane, innymi słowy, liczba całkowita 0 zawsze stanie się liczbą zmiennoprzecinkową 0.
Jeśli użyjesz liczb zmiennoprzecinkowych po obu stronach podziału, Python udzieli odpowiedzi, której oczekujesz.
>>> 10 / 90.0 0.1111111111111111
Więc w twoim przypadku:
>>> float(20-10) / (100-10) 0.1111111111111111 >>> (20-10) / float(100-10) 0.1111111111111111
źródło
Musisz zmienić go na zmiennoprzecinkowy PRZED dzieleniem. To jest:
float(20 - 10) / (100 - 10)
źródło
W Pythonie 2.7
/
operatorem jest dzielenie liczb całkowitych, jeśli dane wejściowe są liczbami całkowitymi:>>>20/15 1 >>>20.0/15.0 1.33333333333 >>>20.0/15 1.33333333333
W Pythonie 3.3
/
operator jest dzieleniem typu float, nawet jeśli dane wejściowe są liczbami całkowitymi.>>> 20/15 1.33333333333 >>>20.0/15 1.33333333333
Do dzielenia liczb całkowitych w Pythonie 3 użyjemy
//
operatora.//
Operator operator dzielenia całkowitego zarówno Pythonie 2,7 Python 3.3.W Pythonie 2.7 i Pythonie 3.3:
>>>20//15 1
A teraz zobacz porównanie
>>>a = 7.0/4.0 >>>b = 7/4 >>>print a == b
W przypadku powyższego programu wynik będzie miał wartość False w Pythonie 2.7 i True w Pythonie 3.3.
W Pythonie 2.7 a = 1,75 ib = 1.
W Pythonie 3.3 a = 1,75 i b = 1,75, tylko dlatego, że
/
jest to dzielenie typu float.źródło
Ma to związek z wersją Pythona, której używasz. Zasadniczo przyjmuje zachowanie C: jeśli podzielisz dwie liczby całkowite, wyniki zostaną zaokrąglone w dół do liczby całkowitej. Pamiętaj również, że Python wykonuje operacje od lewej do prawej, co odgrywa rolę podczas pisania na maszynie.
Przykład: Ponieważ jest to pytanie, które zawsze pojawia się w mojej głowie, gdy wykonuję operacje arytmetyczne (czy powinienem przekonwertować na liczbę zmiennoprzecinkową i jaką liczbę), przedstawiono przykład z tego aspektu:
>>> a = 1/2/3/4/5/4/3 >>> a 0
Kiedy dzielimy liczby całkowite, nie jest zaskakujące, że jest zaokrąglany od dołu.
>>> a = 1/2/3/4/5/4/float(3) >>> a 0.0
Jeśli wpiszemy ostatnią liczbę całkowitą do liczby zmiennoprzecinkowej, nadal otrzymamy zero, ponieważ do czasu, gdy nasza liczba zostanie podzielona przez liczbę zmiennoprzecinkową, już wynosi 0 z powodu dzielenia liczb całkowitych.
>>> a = 1/2/3/float(4)/5/4/3 >>> a 0.0
Taki sam scenariusz jak powyżej, ale przesunięcie typu float nieco bliżej lewej strony.
>>> a = float(1)/2/3/4/5/4/3 >>> a 0.0006944444444444445
Na koniec, kiedy typujemy pierwszą liczbę całkowitą do float, wynik jest pożądany, ponieważ zaczynając od pierwszego dzielenia, czyli od lewej, używamy liczb zmiennoprzecinkowych.
Dodatek 1: Jeśli próbujesz odpowiedzieć na to pytanie, aby poprawić ocenę arytmetyczną, powinieneś to sprawdzić
Dodatek 2: Uważaj na następujący scenariusz:
>>> a = float(1/2/3/4/5/4/3) >>> a 0.0
źródło
Określanie pływaka poprzez umieszczenie znaku „.” po liczbie spowoduje również, że domyślnie będzie się unosić.
>>> 1 / 2 0 >>> 1. / 2. 0.5
źródło
Niech przynajmniej jeden z nich będzie pływający, wtedy będzie to dzielenie typu float, a nie liczba całkowita:
>>> (20.0-10) / (100-10) 0.1111111111111111
Rzucanie wyniku na float jest za późno.
źródło
W Pythonie
cv2
nie zaktualizowano obliczeń podziału. więc musisz uwzględnićfrom __future__ import division
w pierwszej linii programu.źródło
Tak czy inaczej, jest to dzielenie liczb całkowitych. 10/90 = 0. W drugim przypadku po prostu rzucasz 0 do float.
Spróbuj rzutować jeden z operandów „/” na zmiennoprzecinkowy:
float(20-10) / (100-10)
źródło
Rzucasz na float po tym, jak w drugim przykładzie już nastąpił podział. Spróbuj tego:
float(20-10) / float(100-10)
źródło
Jestem nieco zaskoczony, że nikt nie wspomniał, że oryginalny plakat mógł spodobać się racjonalnym liczbom. Jeśli jesteś tym zainteresowany, program Sage oparty na języku Python będzie Cię wspierał . (Obecnie nadal oparty na Pythonie 2.x, chociaż 3.x jest w toku.)
sage: (20-10) / (100-10) 1/9
To nie jest rozwiązanie dla wszystkich, ponieważ wykonuje pewne przygotowania, więc te liczby nie są
int
s, aleInteger
elementami klasy Sage . Mimo to warto o tym wspomnieć jako część ekosystemu Pythona.źródło
Osobiście wolałem wstawić a
1. *
na samym początku. Więc wyrażenie wygląda mniej więcej tak:1. * (20-10) / (100-10)
Jak zawsze robię podział dla jakiejś formuły, takiej jak:
accuracy = 1. * (len(y_val) - sum(y_val)) / len(y_val)
więc nie można po prostu dodać
.0
polubienia20.0
. A w moim przypadku owijanie zfloat()
może trochę stracić na czytelności.źródło