float64 mit pandas to_csv

88

Ich lese eine CSV mit Float-Nummern wie folgt:

Bob,0.085
Alice,0.005

Importieren Sie in einen Datenrahmen und schreiben Sie diesen Datenrahmen an einen neuen Ort

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

Nun pandasfilehat dies:

Bob,0.085000000000000006
Alice,0.0050000000000000001

Was ist los? Vielleicht muss ich auf einen anderen Typ wie float32 oder so umwandeln?

Ich benutze Pandas 0.9.0 und Numpy 1.6.2 .

avances123
quelle
26
Willkommen bei Gleitkommazahlen.
Ignacio Vazquez-Abrams
1
Duplikat von stackoverflow.com/questions/1778368/…
Nathan Villaescusa
1
Ich habe ein Problem erstellt, um es hier etwas genauer zu untersuchen: github.com/pydata/pandas/issues/2069 BEARBEITEN: Wenn Sie können, fügen Sie bitte eine eigenständige Reproduktion des Problems in das GitHub-Problem ein. Ich kann es nicht reproduzieren.
Wes McKinney

Antworten:

164

Wie in den Kommentaren erwähnt, handelt es sich um ein allgemeines Gleitkommaproblem.

Sie können jedoch das float_formatSchlüsselwort von verwenden to_csv, um es auszublenden:

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

oder, wenn Sie nicht möchten, dass 0,0001 auf Null gerundet wird:

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

werde dir geben:

Bob,0.085
Alice,0.005

in Ihrer Ausgabedatei.

Eine Erläuterung zu %gfinden Sie unter Formatspezifikation Mini-Sprache .

bmu
quelle
Ich habe einen Fehler bekommenTypeError: __init__() got an unexpected keyword argument 'float_format'
wander95
Wenn jemand den gleichen Fehler wie @ wander95 hat, müssen Sie wahrscheinlich pandasauf eine neuere Version aktualisieren .
Driftcatcher
10

UPDATE: Die Antwort war zum Zeitpunkt des Schreibens korrekt, und Gleitkomma-Genauigkeit wird standardmäßig immer noch nicht mit to_csv / read_csv erhalten (Kompromiss zwischen Präzision und Leistung; Standardeinstellungen begünstigen die Leistung).

Heutzutage gibt es das float_formatArgument fürpandas.DataFrame.to_csv und das float_precisionArgument fürpandas.from_csv .

Das Original ist immer noch lesenswert, um das Problem besser zu verstehen.


Es war ein Fehler in Pandas, nicht nur in der Funktion "to_csv", sondern auch in "read_csv". Es ist kein allgemeines Gleitkomma-Problem, obwohl es stimmt, dass Gleitkomma-Arithmetik ein Thema ist, das vom Programmierer etwas Sorgfalt verlangt. Dieser Artikel unten verdeutlicht ein wenig dieses Thema:

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

Ein klassischer Einzeiler, der das "Problem" zeigt, ist ...

>>> 0.1 + 0.1 + 0.1
0.30000000000000004

... die nicht wie erwartet 0,3 anzeigt. Wenn Sie die Berechnung jedoch mit Festkomma-Arithmetik durchführen und erst im letzten Schritt Gleitkomma-Arithmetik verwenden , funktioniert sie wie erwartet. Sieh dir das an:

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

Wenn Sie dieses Problem dringend umgehen müssen, empfehle ich Ihnen, eine weitere CSV-Datei zu erstellen, die alle Zahlen als Ganzzahlen enthält, z. B. Multiplikation mit 100, 1000 oder einem anderen Faktor, der sich als praktisch herausstellt. Lesen Sie in Ihrer Anwendung die CSV-Datei wie gewohnt, und Sie erhalten diese ganzzahligen Zahlen zurück. Konvertieren Sie diese Werte dann in Gleitkommawerte, indem Sie sie durch denselben Faktor dividieren, den Sie zuvor multipliziert haben.

Richard Gomes
quelle