Escribir un DataFrame de pandas en un archivo CSV

846

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 solucionar esto fácilmente (es decir, tengo caracteres Unicode en mi marco de datos)? ¿Y hay alguna manera de escribir en un archivo delimitado por tabulaciones en lugar de un CSV usando, por ejemplo, un método de "tabulación" (que no creo que exista)?

0
1211

Para delimitar por tabulación puedes 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')
3
  • 83
    Agregaría index=Falsepara soltar el índice.
    Medhat
    3/07/19 a las 20:48
  • 25
    Inicialmente estaba confundido en cuanto a cómo encontré una respuesta a la pregunta que ya había escrito hace 7 años.
    Hayden
    30/01/20 a las 17:49
  • Solo un pequeño aviso para otras personas que usan la función: termine el nombre de su archivo con .csvNo quiero admitir cuántas veces me olvido de hacer eso. 15 de agosto a las 5:20
296

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

Puede evitarlo pasando un Falsevalor booleano al indexparámetro.

Algo parecido a:

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

Entonces, si su objeto DataFrame es algo como:

  Color  Number
0   red     22
1  blue     10

El archivo csv almacenará:

Color,Number
red,22
blue,10

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

,Color,Number
0,red,22
1,blue,10
1
  • ¿Qué pasa si se desea la indexación, pero también debe tener un título? ¿Solo usas df.rename_axis('index_name')? eso no altera el archivo en sí
    Zap
    27 de mayo de 2018 a las 19:53
34

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 necesitará 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 eliminar 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.

Escribe a CSV ma dude

Footnotes

  1. The default separator is assumed to be a comma (','). Don't change this unless you know you need to.
  2. By default, the index of df is written as the first column. If your DataFrame does not have an index (IOW, the df.index is the default RangeIndex), then you will want to set index=False when writing. To explain this in a different way, if your data DOES have an index, you can (and should) use index=True or just leave it out completely (as the default is True).
  3. It would be wise to set this parameter if you are writing string data so that other applications know how to read your data. This will also avoid any potential UnicodeEncodeErrors you might encounter while saving.
  4. Compression is recommended if you are writing large DataFrames (>100K rows) to disk as it will result in much smaller output files. OTOH, it will mean the write time will increase (and consequently, the read time since the file will need to be decompressed).
21

Puede probar algo más si tiene problemas para codificar en 'utf-8' y desea ir celda por celda, puede 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 comprobar la codificación de las columnas mediante:

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

Advertencia: errors = 'ignore' simplemente omitirá el carácter, p. Ej.

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
18

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) 

Por ejemplo, si desea almacenar el archivo en el mismo directorio donde está su script, con codificación utf-8 y tabulación como separador :

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

A veces, se enfrenta a estos problemas si también especifica la codificación UTF-8. Le recomiendo que especifique la codificación mientras lee el archivo y la misma codificación mientras escribe en el archivo. Esto podría resolver su problema.

8

podría no ser la respuesta para este caso, pero como tenía el mismo mensaje de error .to_csvque probé .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')
1
  • Obtuvo el error en el segundo, ya que parece que lo usó .toCSVy no .to_csv. Olvidaste el subrayado
    Kyle C
    4 feb 2019 a las 17:51
0

Si la solución no funciona para nadie o si el CSV se está estropeando, simplemente elimínelo sep='\t'de la línea de esta manera:

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