Zapisz listę DataFrames w wieloarkuszowym arkuszu kalkulacyjnym Excel

89

Jak mogę wyeksportować listę ramek danych do jednego arkusza kalkulacyjnego Excel?
Dokumenty dotyczące to_excelstanu:

Uwagi
Jeśli przekazujesz istniejący obiekt ExcelWriter, arkusz zostanie dodany do istniejącego skoroszytu. Może to służyć do zapisywania różnych ramek danych w jednym skoroszycie

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

Po tym pomyślałem, że mógłbym napisać funkcję, która zapisuje listę DataFrames w jednym arkuszu kalkulacyjnym w następujący sposób:

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

Jednak (z listą dwóch małych ramek DataFrame, z których każda może być zapisywana to_excelindywidualnie), zgłaszany jest wyjątek (Edycja: usunięto śledzenie) :

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

Prawdopodobnie nie dzwonię ExcelWriterpoprawnie, jak mam to zrobić?

Andy Hayden
źródło

Odpowiedzi:

135

Powinieneś używać własnej ExcelWriterklasy pand :

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

Wtedy save_xlsfunkcja działa zgodnie z oczekiwaniami:

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
źródło
11
Jak oceniasz szybkość tego? Wczoraj próbowałem zrobić to samo i odkryłem, że zapisanie ramki danych z 2000 kolumnami do pliku .xlsx zajmowało około 16 sekund na 100 wierszy na przyzwoitej stacji roboczej z dyskiem SSD. Niektóre szybkie profilowanie z% prun w ipythonie pokazało, że jest to spowodowane przetwarzaniem XML. W końcu dostałem dane z Excela, przechodząc przez CSV, ponieważ prędkość ExcelWriter była zbyt niska.
snth
6
Wciąż tak wolno w 2018 r.
stmax
2
Możesz także używać ExcelWriterjako menedżera kontekstu. with ExcelWriter(xls_path) as writer: df.to_excel(writer, sheet_name)
BallpointBen
2
Dzięki Andy. Czy mógłbyś to wyjaśnić 'sheet%s' % n? Co to robi i jak działa?
Bowen Liu,
2
@BowenLiu To tylko nazwanie arkuszy na arkusz1, arkusz2 itd.
xiaomy
17

Jeśli ktoś potrzebuje przykładu, jak to zrobić ze słownikiem ramek danych:

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

przykład: save_xls(dict_df = my_dict, path = '~/my_path.xls')

Jared Marks
źródło
To naprawdę uratowało mi dzień. Ale jest jedna rzecz, której nie rozumiem, chociaż zadziałała. Co robi ta część '%s' % key? Czy mógłbyś to wyjaśnić? Dzięki!
Bowen Liu
@BowenLiu, który pobiera wartość klucza słownika i używa go jako nazwy strony w arkuszu programu Excel. „% s” to symbol zastępczy wypełniony „kluczem”. Mam nadzieję, że to pomoże.
Jared Marks