Guardar lista de DataFrames en una hoja de cálculo de Excel de varias hojas

89

¿Cómo puedo exportar una lista de DataFrames a una hoja de cálculo de Excel?
Los documentos para el to_excelestado:

Notas
Si pasa un objeto ExcelWriter existente, la hoja se agregará al libro de trabajo existente. Esto se puede usar para guardar diferentes DataFrames en un libro de trabajo

writer = ExcelWriter('output.xlsx')
df1.to_excel(writer, 'sheet1')
df2.to_excel(writer, 'sheet2')
writer.save()

Después de esto, pensé que podría escribir una función que guarde una lista de DataFrames en una hoja de cálculo de la siguiente manera:

from openpyxl.writer.excel import ExcelWriter
def save_xls(list_dfs, xls_path):
    writer = ExcelWriter(xls_path)
    for n, df in enumerate(list_dfs):
        df.to_excel(writer,'sheet%s' % n)
    writer.save()

Sin embargo (con una lista de dos DataFrames pequeños, cada uno de los cuales se puede guardar to_excelindividualmente), se genera una excepción (Editar: rastreo eliminado) :

AttributeError: 'str' object has no attribute 'worksheets'

Presumiblemente no estoy llamando ExcelWritercorrectamente, ¿cómo debería estar para hacer esto?

Andy Hayden
fuente

Respuestas:

135

Deberías estar usando la propia ExcelWriterclase de pandas :

from pandas import ExcelWriter
# from pandas.io.parsers import ExcelWriter

Entonces la save_xlsfunción funciona como se esperaba:

def save_xls(list_dfs, xls_path):
    with ExcelWriter(xls_path) as writer:
        for n, df in enumerate(list_dfs):
            df.to_excel(writer,'sheet%s' % n)
        writer.save()
Andy Hayden
fuente
11
¿Cómo encuentra la velocidad de esto? Ayer intenté hacer lo mismo y descubrí que escribir un marco de datos con 2000 columnas en un archivo .xlsx estaba tomando alrededor de 16 s por 100 filas en una estación de trabajo decente con unidad de estado sólido. Algunos perfiles rápidos con% prun en ipython mostraron que esto se debía al procesamiento XML. Al final obtuve los datos de Excel yendo a través de CSV porque la velocidad de ExcelWriter era prohibitivamente lenta.
2013
6
Sigue siendo tan lento en 2018.
stmax
2
También puede utilizarlo ExcelWritercomo administrador de contexto. with ExcelWriter(xls_path) as writer: df.to_excel(writer, sheet_name)
BallpointBen
2
Gracias Andy. ¿Te importaría explicar un 'sheet%s' % npoco, por favor? ¿Qué hace y cómo funciona?
Bowen Liu
2
@BowenLiu Eso es solo nombrar las hojas a sheet1, sheet2, etc.
xiaomy
17

En caso de que alguien necesite un ejemplo de cómo hacer esto con un diccionario de marcos de datos:

from pandas import ExcelWriter

def save_xls(dict_df, path):
"""
Save a dictionary of dataframes to an excel file, with each dataframe as a seperate page
"""

    writer = ExcelWriter(path)
    for key in dict_df:
        dict_df[key].to_excel(writer, key)

    writer.save()

ejemplo: save_xls(dict_df = my_dict, path = '~/my_path.xls')

Jared Marks
fuente
Esto realmente me salvó el día. Pero hay una cosa que no entiendo aunque funcionó. ¿Qué hace la pieza '%s' % key? ¿Te importaría explicarlo? ¡Gracias!
Bowen Liu
@BowenLiu que toma el valor de la clave del diccionario y lo usa para el nombre de la página en la hoja de Excel. '% s' es un marcador de posición que se completa con "clave". Espero que ayude.
Jared Marks