Escribir un DataFrame de pandas en un archivo CSV


716

Tengo un marco de datos en pandas que me gustaría escribir en un archivo CSV. Estoy haciendo esto usando:

df.to_csv('out.csv')

Y obteniendo el error:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u03b1' in position 20: ordinal not in range(128)

¿Hay alguna forma de evitar esto fácilmente (es decir, tengo caracteres Unicode en mi marco de datos)? ¿Y hay una manera de escribir en un archivo delimitado por tabulaciones en lugar de un CSV utilizando, por ejemplo, un método 'to-tab' (que no creo que exista)?

Respuestas:


1046

Para delimitar por una pestaña puede usar el separgumento de to_csv:

df.to_csv(file_name, sep='\t')

Para usar una codificación específica (por ejemplo, 'utf-8') use el encodingargumento:

df.to_csv(file_name, sep='\t', encoding='utf-8')

32
Yo agregaría index=Falsepara soltar el índice.
Medhat

12
Al principio estaba confundido sobre cómo encontré una respuesta a la pregunta que ya había escrito hace 7 años.
Hayden

251

Cuando esté almacenando un DataFrameobjeto en un archivo csv utilizando el to_csvmétodo, probablemente no necesitará almacenar los índices anteriores de cada fila del DataFrameobjeto.

Puede evitar eso pasando un Falsevalor booleano al indexparámetro.

Algo así como:

df.to_csv(file_name, encoding='utf-8', index=False)

Entonces, si su objeto DataFrame es algo así como:

  Color  Number
0   red     22
1  blue     10

El archivo csv almacenará:

Color,Number
red,22
blue,10

en lugar de (el caso cuando se pasó el valor predeterminado True )

,Color,Number
0,red,22
1,blue,10

¿Qué pasa si se desea la indexación, pero también debe tener un título? ¿Solo lo usas df.rename_axis('index_name')? eso no altera el archivo en sí mismo
Zap

21

Para escribir un DataFrame de pandas en un archivo CSV, necesitará DataFrame.to_csv. Esta función ofrece muchos argumentos con valores predeterminados razonables que la mayoría de las veces tendrá que anular para adaptarse a su caso de uso específico. Por ejemplo, es posible que desee utilizar un separador diferente, cambiar el formato de fecha y hora o descartar el índice al escribir. to_csvtiene argumentos que puede pasar para abordar estos requisitos.

Aquí hay una tabla que enumera algunos escenarios comunes de escritura en archivos CSV y los argumentos correspondientes que puede usar para ellos.

Escribir a CSV ma dude

Notas al pie

  1. Se supone que el separador predeterminado es una coma (',' ). No cambie esto a menos que sepa que necesita hacerlo.
  2. Por defecto, el índice de dfse escribe como la primera columna. Si su DataFrame no tiene un índice (IOW, df.indexes el predeterminado RangeIndex), entonces querrá configurarlo index=Falseal escribir. Para explicar esto de una manera diferente, si sus datos TIENEN un índice, puede (y debe) usarlo index=Trueo simplemente dejarlo por completo (como el valor predeterminado es True).
  3. Sería conveniente establecer este parámetro si está escribiendo datos de cadena para que otras aplicaciones sepan cómo leer sus datos. Esto también evitará cualquier potencial UnicodeEncodeErrors que pueda encontrar al guardar.
  4. Se recomienda la compresión si está escribiendo DataFrames grandes (> 100K filas) en el disco, ya que dará como resultado archivos de salida mucho más pequeños. OTOH, significará que el tiempo de escritura aumentará (y en consecuencia, el tiempo de lectura ya que el archivo deberá descomprimirse).

18

Algo más que puedes probar si tienes problemas para codificar 'utf-8' y quieres ir celda por celda, puedes intentar lo siguiente.

Python 2

(Donde "df" es su objeto DataFrame).

for column in df.columns:
    for idx in df[column].index:
        x = df.get_value(idx,column)
        try:
            x = unicode(x.encode('utf-8','ignore'),errors ='ignore') if type(x) == unicode else unicode(str(x),errors='ignore')
            df.set_value(idx,column,x)
        except Exception:
            print 'encoding error: {0} {1}'.format(idx,column)
            df.set_value(idx,column,'')
            continue

Entonces intenta:

df.to_csv(file_name)

Puede verificar la codificación de las columnas de la siguiente manera:

for column in df.columns:
    print '{0} {1}'.format(str(type(df[column][0])),str(column))

Advertencia: errors = 'ignore' simplemente omitirá el carácter, por ejemplo

IN: unicode('Regenexx\xae',errors='ignore')
OUT: u'Regenexx'

Python 3

for column in df.columns:
    for idx in df[column].index:
        x = df.get_value(idx,column)
        try:
            x = x if type(x) == str else str(x).encode('utf-8','ignore').decode('utf-8','ignore')
            df.set_value(idx,column,x)
        except Exception:
            print('encoding error: {0} {1}'.format(idx,column))
            df.set_value(idx,column,'')
            continue

11

A veces enfrenta estos problemas si especifica también la codificación UTF-8. Le recomiendo que especifique la codificación al leer el archivo y la misma codificación al escribir en el archivo. Esto podría resolver tu problema.


7

Ejemplo de exportación en archivo con ruta completa en Windows y en caso de que su archivo tenga encabezados :

df.to_csv (r'C:\Users\John\Desktop\export_dataframe.csv', index = None, header=True) 

Ejemplo si desea almacenar en la carpeta en el mismo directorio donde está su script, con codificación utf-8 y tabulador como separador :

df.to_csv(r'./export/dftocsv.csv', sep='\t', encoding='utf-8', header='true')

7

podría no ser la respuesta para este caso, pero como tenía el mismo mensaje de error .to_csvque intenté .toCSV('name.csv')y el mensaje de error era diferente (" SparseDataFrame' object has no attribute 'toCSV'). Así que el problema se resolvió convirtiendo el marco de datos en un marco de datos denso

df.to_dense().to_csv("submission.csv", index = False, sep=',', encoding='utf-8')

Recibió el error en el segundo, ya que parece que lo usó .toCSVy no .to_csv. Olvidaste el guión bajo
Kyle C
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.