float64 con i panda to_csv


93

Sto leggendo un CSV con numeri float come questo:

Bob,0.085
Alice,0.005

E importa in un dataframe e scrivi questo dataframe in una nuova posizione

df = pd.read_csv(orig)
df.to_csv(pandasfile)

Ora questo pandasfileha:

Bob,0.085000000000000006
Alice,0.0050000000000000001

Cosa succede? forse devo eseguire il cast su un tipo diverso come float32 o qualcosa del genere?

Sto usando panda 0.9.0 e numpy 1.6.2 .


28
Benvenuto nei numeri in virgola mobile.
Ignacio Vazquez-Abrams


1
Ho creato un problema da esaminare un po 'più in dettaglio qui: github.com/pydata/pandas/issues/2069 EDIT: Se puoi, per favore metti una riproduzione indipendente del problema sul problema di GitHub. Non sono in grado di riprodurlo.
Wes McKinney

Risposte:


168

Come accennato nei commenti, è un problema generale in virgola mobile.

Tuttavia puoi usare la float_formatparola chiave di to_csvper nasconderlo:

df.to_csv('pandasfile.csv', float_format='%.3f')

oppure, se non vuoi che 0.0001 venga arrotondato a zero:

df.to_csv('pandasfile.csv', float_format='%g')

ti darà:

Bob,0.085
Alice,0.005

nel file di output.

Per una spiegazione %g, vedere Mini-linguaggio per la specifica del formato .


Ho ricevuto un erroreTypeError: __init__() got an unexpected keyword argument 'float_format'
wander95

Se qualcuno ha lo stesso errore di @ wander95, probabilmente è necessario eseguire l'aggiornamento pandasa una versione più recente.
driftcatcher

10

AGGIORNAMENTO: la risposta era accurata al momento della scrittura e la precisione in virgola mobile non è ancora qualcosa che si ottiene per impostazione predefinita con to_csv / read_csv (compromesso precisione-prestazioni; i valori predefiniti favoriscono le prestazioni).

Al giorno d'oggi c'è l' float_formatargomento disponibile perpandas.DataFrame.to_csv e l' float_precisionargomento disponibile perpandas.from_csv .

Vale ancora la pena leggere l'originale per avere una migliore comprensione del problema.


Era un bug nei panda, non solo nella funzione "to_csv", ma anche in "read_csv". Non è un problema generale in virgola mobile, nonostante sia vero che l' aritmetica in virgola mobile è un argomento che richiede una certa attenzione da parte del programmatore. Questo articolo di seguito chiarisce un po 'questo argomento:

http://docs.python.org/2/tutorial/floatingpoint.html

Un classico one-liner che mostra il "problema" è ...

>>> 0.1 + 0.1 + 0.1
0.30000000000000004

... che non mostra 0,3 come ci si aspetterebbe. D'altra parte, se gestisci il calcolo utilizzando l' aritmetica in virgola fissa e solo nell'ultimo passaggio utilizzi l' aritmetica in virgola mobile , funzionerà come previsto. Guarda questo:

>>> (1 + 1 + 1)  * 1.0 / 10
0.3

Se hai un disperato bisogno di aggirare questo problema, ti consiglio di creare un altro file CSV che contenga tutte le cifre come numeri interi, ad esempio moltiplicando per 100, 1000 o altro fattore che risulta conveniente. All'interno dell'applicazione, leggi il file CSV come al solito e otterrai indietro quelle cifre intere. Quindi converti quei valori in virgola mobile, dividendoli per lo stesso fattore che hai moltiplicato prima.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.