2012-04-04 11 views
14

Używam funkcji arange do definiowania moich iteracji pętli for i uzyskiwania nieoczekiwanych wyników.python numpy arange nieoczekiwane wyniki

i = arange(7.8,8.4,0.05) 
print i 

yeilds następujące:

[ 7.8 7.85 7.9 7.95 8. 8.05 8.1 8.15 8.2 8.25 8.3 8.35 8.4 ] 

jeszcze użyciu wartości stop 8,35 następująco

i = arange(7.8,8.35,0.05) 

daje następujące

[ 7.8 7.85 7.9 7.95 8. 8.05 8.1 8.15 8.2 8.25 8.3 ] 

Ale chcę moją ofertą do koniec o 8,35! Wiem, że mogę użyć wartości zatrzymania> 8,35 i < 8,4, aby osiągnąć mój wynik, ale dlaczego jest inny i według mnie niespójny?

Edycja: używam wersji 2.7

+0

Która wersja Pythona używasz? –

+0

Używam 2.7! – smashtastic

+0

Prostym sposobem na uniknięcie tych problemów jest użycie 'arrange = (7.8,8.351,0.05)' – Thiru

Odpowiedz

9

Być może ma to związek z ograniczeniami dotyczącymi liczb zmiennoprzecinkowych. Ze względu na precyzję maszyny nie jest możliwe zapisanie każdej możliwej wartości idealnie jako zmiennoprzecinkowej. Na przykład:

>>> 8.4 
8.4000000000000004 
>>> 8.35 
8.3499999999999996 

Tak, 8.4 jako zmiennoprzecinkowych jest nieco większa niż rzeczywista wartość 8,4, a 8,35 jako zmiennoprzecinkowych jest odrobinę mniej.

+1

Wydaje się, że to wyjście z pythonem 2.6, ale z wersją 2.7, >>> 8.4 wychodzi jako 8.4 – avasal

+3

Tak, to jest interesujące. Wygląda na to, że zmienili sposób, w jaki pływaki są drukowane, chociaż podstawowa liczba nadal jest taka sama (trochę niepoprawna), co można zobaczyć porównując wartości szesnastkowe dla spławików w Pythonie 2.6 i 2.7. –

+0

Myślę, że to wyjaśnia, co widzę - dzięki! – smashtastic

18

Zgaduję, że widzisz efekty zmiennoprzecinkowej zaokrąglenia.

numpy.arange robi to samo, co python's range: Nie zawiera "punktu końcowego". (Np range(0, 4, 2) przyniesie [0,2] zamiast [0,2,4])

jednak do unoszenia etapy punktowych błędów zaokrąglania się gromadzić i czasami ostatnią wartością będzie w rzeczywistości zawierać końcowy.

Jak wskazano w dokumentacji arange:

Przy użyciu etap nie jest liczbą całkowitą, na przykład 0,1, wyniki często nie być spójne. W takich przypadkach lepiej jest używać linspace.

numpy.linspace Generuje określoną liczbę punktów między punktem początkowym i końcowym. Nawiasem mówiąc, domyślnie zawiera punkty końcowe.

+0

hi - Próbowałem znaleźć dokumentację pomocy online dla obszaru bankowego, ale jest to dziwnie puste ... czy masz odpowiedni link ? – smashtastic

+1

http://docs.scipy.org/doc/numpy-1.6.0/reference/generated/numpy.linspace.html Alternatywnie, możesz po prostu zrobić 'pydoc numpy.linspace' lub jeśli jesteś w interpreterze python' help (numpy.linspace) 'lub w' ipython', to po prostu 'numpy.linspace?'. –

+0

jest to oczywiste w dokumentach, ale nie sprawia, że ​​numpy.arange jest przydatne? – marbel

3

pomocą funkcji arange mówi

For floating point arguments, the length of the result is 
    ``ceil((stop - start)/step)``. Because of floating point overflow, 
    this rule may result in the last element of `out` being greater 
    than `stop`. 

dla Pythona 2.7, konwersja liczb zmiennoprzecinkowych i ciągi są teraz poprawnie zaokrąglone na większości platform.

w 2,7

>>> float(repr(2.3)) 
2.3 

w 2,6

>>> float(repr(2.3)) 
2.2999999999999998 
1

miałem ten sam problem i wdrożone własną funkcję, aby skorygować ten problem z zaokrągleniem numpy.arange:

import numpy as np 
def my_arange(a, b, dr, decimals=6): 
    res = [a] 
    k = 1 
    while res[-1] < b: 
     tmp = round(a + k*dr,decimals) 
     if tmp > b: 
      break 
     res.append(tmp) 
     k+=1 

    return np.asarray(res) 
+0

to było przydatne. dzięki! – marbel

Powiązane problemy