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)?

usuario7289
fuente

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')
Andy Hayden
fuente
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
Sayan Sil
fuente
¿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).
cs95
fuente
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
Glen Thompson
fuente
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.

Harsha Komarraju
fuente
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')
Harvey
fuente
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')
Cartera Yury
fuente
Recibió el error en el segundo, ya que parece que lo usó .toCSVy no .to_csv. Olvidaste el guión bajo
Kyle C