2012-04-04 16 views
14

Sto utilizzando la funzione arange per definire le it per iterazioni di loop e ottenere risultati imprevisti.python numpy arange risultati imprevisti

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

yeilds il seguente:

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

ancora usando il valore di arresto di 8.35 come segue

i = arange(7.8,8.35,0.05) 

produce il seguente

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

Ma io voglio la mia fascia di fine alle 8.35! So che posso usare il valore di stop di> 8,35 e < 8.4 per raggiungere il mio risultato, ma perché è diverso e nella mia mente, incoerente?

Edit: Sto usando la versione 2.7

+0

Quale versione di Python stai usando? –

+0

Sto usando 2.7! – smashtastic

+0

Un modo semplice per evitare questi problemi è usare 'arrangement = (7.8,8.351,0.05)' – Thiru

risposta

9

Forse ha a che fare con limitazioni numeri in virgola mobile. A causa della precisione della macchina, non è possibile memorizzare perfettamente ogni valore immaginabile come un punto mobile. Ad esempio:

>>> 8.4 
8.4000000000000004 
>>> 8.35 
8.3499999999999996 

Quindi, 8.4 in virgola mobile è leggermente maggiore del valore effettivo di 8,4, mentre 8.35 in virgola mobile è un pochino meno.

+1

sembra uscita con python 2.6 ma con 2.7, >>> 8.4 esce come 8.4 – avasal

+3

Quindi, è interessante. Sembra che abbiano cambiato il modo in cui i float vengono stampati, sebbene il numero sottostante sia sempre lo stesso (leggermente errato), che puoi vedere confrontando i valori esadecimali per i float in Python 2.6 e 2.7. –

+0

Immagino che questo spieghi cosa sto vedendo - grazie! – smashtastic

18

Sto indovinando che si sta vedendo gli effetti di cui al punto arrotondamenti floating.

numpy.arange fa la stessa cosa di python range: non include il "punto finale". (Ad esempio range(0, 4, 2) produrrà [0,2] anziché [0,2,4])

Tuttavia, per il galleggiamento gradini punto, gli errori di arrotondamento sono accumulo, e occasionalmente l'ultimo valore sarà effettivamente includere il punto finale.

Come indicato nella documentazione per arange:

Quando si utilizza un passo non intera, come 0,1, i risultati spesso non essere coerenti. È meglio usare linspace per questi casi.

numpy.linspace genera un numero specificato di punti tra un punto iniziale e uno finale. Per inciso, include gli endpoint per impostazione predefinita.

+0

hi - Ho provato a trovare i documenti di aiuto online per linspace ma è stranamente vuoto ... hai un link adatto ? – smashtastic

+1

http://docs.scipy.org/doc/numpy-1.6.0/reference/generated/numpy.linspace.html In alternativa, puoi semplicemente fare 'pydoc numpy.linspace' o se sei in un interprete python' help (numpy.linspace) ', o in' ipython', è solo 'numpy.linspace?'. –

+0

questo è chiaro nei documenti, ma non rende numpy.arange utile lo fa? – marbel

3

l'aiuto della funzione arange dice

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`. 

per pitone 2.7, conversioni tra numeri a virgola mobile e stringhe sono ora arrotondati correttamente sulla maggior parte delle piattaforme.

in 2,7

>>> float(repr(2.3)) 
2.3 

in 2,6

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

Ho avuto lo stesso problema e ho implementato il mio propria funzione per correggere questo problema di arrotondamento con 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

questo è stato utile. Grazie! – marbel

Problemi correlati