Python Pandas escriben en sql con valores NaN

Estoy tratando de leer unos cientos de tablas de ascii y luego escribirlas en mySQL. Parece fácil de hacer con Pandas, pero cometí un error que no tiene sentido para mí:

Tengo un dataframe de 8 columnas. Aquí está la lista de columnas / índice:

metricDF.columns Index([u'FID', u'TYPE', u'CO', u'CITY', u'LINENO', u'SUBLINE', u'VALUE_010', u'VALUE2_015'], dtype=object) 

Luego uso to_sql para agregar los datos a mySQL

 metricDF.to_sql(con=con, name=seqFile, if_exists='append', flavor='mysql') 

Me sale un error extraño de que una columna es “nan”:

 OperationalError: (1054, "Unknown column 'nan' in 'field list'") 

Como puedes ver todas mis columnas tienen nombres. Me doy cuenta de que el soporte de mysql / sql para escritura aparece en desarrollo, así que quizás esa sea la razón ¿Si es así, hay alguna solución? Cualquier sugerencia sería muy apreciada.

Actualización : a partir de pandas 0.15, to_sql admite la escritura de valores NaN (se escribirán como NULL en la base de datos), por lo que la solución que se describe a continuación ya no será necesaria (consulte https://github.com/pydata/pandas/pull/ 8208 ).
Pandas 0.15 se lanzará en octubre próximo, y la característica se fusiona en la versión de desarrollo.


Esto se debe probablemente a los valores de NaN en su tabla, y este es un defecto conocido en el momento en que las funciones de pandas sql no manejan bien los NaN ( https://github.com/pydata/pandas/issues/2754 , https: //github.com/pydata/pandas/issues/4199 )

Como solución temporal en este momento (para las versiones de pandas 0.14.1 y anteriores), puede convertir manualmente los valores de nan a Ninguno con:

 df2 = df.astype(object).where(pd.notnull(df), None) 

y luego escribir el dataframe a SQL. Sin embargo, esto convierte todas las columnas al tipo de objeto. Debido a esto, debe crear la tabla de base de datos basada en el dataframe original. Por ejemplo, si su primera fila no contiene NaN s:

 df[:1].to_sql('table_name', con) df2[1:].to_sql('table_name', con, if_exists='append') 

el uso de la solución anterior cambiará el tipo de columna de float64 a object_.

He encontrado una mejor solución, solo agregue la siguiente función _write_mysql:

 from pandas.io import sql def _write_mysql(frame, table, names, cur): bracketed_names = ['`' + column + '`' for column in names] col_names = ','.join(bracketed_names) wildcards = ','.join([r'%s'] * len(names)) insert_query = "INSERT INTO %s (%s) VALUES (%s)" % ( table, col_names, wildcards) data = [[None if type(y) == float and np.isnan(y) else y for y in x] for x in frame.values] cur.executemany(insert_query, data) 

Y luego anula su implementación en pandas como se muestra a continuación:

 sql._write_mysql = _write_mysql 

Con este código, los valores de nan se guardarán correctamente en la base de datos sin alterar el tipo de columna.

NaT a MySQL aún no se maneja en pandas 15.2