float64 con pandas to_csv

88

Estoy leyendo un CSV con números flotantes como este:

Bob,0.085
Alice,0.005

E importe en un marco de datos y escriba este marco de datos en un nuevo lugar

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

Ahora esto pandasfiletiene:

Bob,0.085000000000000006
Alice,0.0050000000000000001

¿Qué ocurre? tal vez tengo que lanzar a un tipo diferente como float32 o algo así?

Estoy usando pandas 0.9.0 y numpy 1.6.2 .

avances123
fuente
26
Bienvenido a los números de coma flotante.
Ignacio Vazquez-Abrams
1
Duplicado de stackoverflow.com/questions/1778368/…
Nathan Villaescusa
1
Creé un problema para examinarlo con un poco más de detalle aquí: github.com/pydata/pandas/issues/2069 EDITAR: Si puede, coloque una reproducción independiente del problema en el problema de GitHub. No puedo reproducirlo.
Wes McKinney

Respuestas:

165

Como se menciona en los comentarios, es un problema general de coma flotante.

Sin embargo, puede usar la float_formatpalabra clave de to_csvpara ocultarlo:

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

o, si no desea que 0,0001 se redondee a cero:

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

Te regalaré:

Bob,0.085
Alice,0.005

en su archivo de salida.

Para obtener una explicación de %g, consulte Mini-idioma de especificación de formato .

bmu
fuente
Recibí un errorTypeError: __init__() got an unexpected keyword argument 'float_format'
wander95
Si alguien tiene el mismo error que @ wander95, probablemente necesite actualizar pandasa una versión más nueva.
cazador de deriva
10

ACTUALIZACIÓN: La respuesta era precisa en el momento de escribir este artículo, y la precisión del punto flotante aún no es algo que se obtiene de forma predeterminada con to_csv / read_csv (compensación precisión-rendimiento; los valores predeterminados favorecen el rendimiento).

Hoy en día existe el float_formatargumento disponible parapandas.DataFrame.to_csv y el float_precisionargumento disponible parapandas.from_csv .

Todavía vale la pena leer el original para comprender mejor el problema.


Fue un error en pandas, no solo en la función "to_csv", sino también en "read_csv". No es un problema general del punto flotante, a pesar de que es cierto que la aritmética del punto flotante es un tema que exige cierto cuidado por parte del programador. Este artículo a continuación aclara un poco este tema:

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

Un clásico de una sola línea que muestra el "problema" es ...

>>> 0.1 + 0.1 + 0.1
0.30000000000000004

... que no muestra 0.3 como cabría esperar. Por otro lado, si maneja el cálculo usando aritmética de punto fijo y solo en el último paso emplea aritmética de punto flotante , funcionará como espera. Mira esto:

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

Si necesita desesperadamente evitar este problema, le recomiendo que cree otro archivo CSV que contenga todas las cifras como números enteros, por ejemplo, multiplicando por 100, 1000 u otro factor que resulte conveniente. Dentro de su aplicación, lea el archivo CSV como de costumbre y obtendrá esas cifras enteras. Luego, convierta esos valores a punto flotante, dividiéndolos por el mismo factor que multiplicaste antes.

Richard Gomes
fuente