#python #pandas #openpyxl
#python #pandas #openpyxl
Вопрос:
Я сохраняю a pandas DataFrame
на листе Excel. Когда я повторно запускаю свой код, я хочу, чтобы лист был полностью перезаписан. Это важно, потому что мой код записывает в один и тот же файл несколько разных раз, то есть загружает и сохраняет определенные листы в разные моменты, не желая мешать листам, которые в данный момент не изменяются. Из-за этого, если новая итерация кода создает меньше строк или столбцов, старые данные все равно будут там. Например, если итерация # 1 выдает 500 строк, а итерация # 2 выдает только 499, эта 500-я строка все равно будет отображаться в моем файле Excel.
Я знаю, что мог бы перебрать все ячейки и установить их значения None
, но я подумал, что было бы более эффективно remove
полностью использовать данный лист create_sheet
с тем же именем листа, а затем сохранить DataFrame
его на новом листе. Приведенный ниже код представляет собой MRE того, что я пытаюсь сделать. Он успешно удаляет лист, создает новый и сохраняет файл, но to_excel
, похоже, он не выполняется. Результирующий файл Excel содержит лист ‘test’, но он пустой.
import pandas as pd
import numpy as np
import openpyxl
from openpyxl import load_workbook
from openpyxl import Workbook
df_data = {'A': np.random.randint(1, 50, 20),
'B': np.random.randint(1, 50, 20),
'C': np.random.randint(1, 50, 20),
'D': np.random.randint(1, 50, 20)}
df = pd.DataFrame(data=df_data)
fn = 'test.xlsx'
sheet = 'test'
df.to_excel(fn, sheet_name=sheet)
df2 = pd.read_excel(fn, sheet_name=sheet, index_col=0)
df2.drop(columns=['A'], inplace=True)
book = load_workbook(fn)
writer = pd.ExcelWriter(fn, engine='openpyxl')
writer.book = book
writer.sheets = dict((ws.title, ws) for ws in book.worksheets)
s = book[sheet]
book.remove(s)
book.create_sheet(sheet, 0)
#THIS CODE WILL ACTUALLY WRITE TO THE SHEET, BUT df2 WILL NOT
#s2 = book[sheet]
#s2['A1'] = 'This will write to the sheet'
df2.to_excel(writer, sheet_name=sheet)
writer.save()
Обратите внимание, что мой закомментированный код будет записан в соответствующий лист, если он не раскомментирован. Кажется, это просто to_excel
строка, которая не работает.
Ответ №1:
Вы могли бы сделать это с помощью функции:
import pandas as pd
def write2excel(filename,sheetname,dataframe):
with pd.ExcelWriter(filename, engine='openpyxl', mode='a') as writer:
workBook = writer.book
try:
workBook.remove(workBook[sheetname])
except:
print("There is no such sheet in this file")
finally:
dataframe.to_excel(writer, sheet_name=sheetname,index=False)
writer.save()
После этого, предполагая, что у вас есть фрейм данных df
, рабочая книга Myfile.xlsx
и лист, который вы хотите перезаписать THE_sheet
, выполните
write2excel('Myfile.xlsx','THE_sheet',df)
Комментарии:
1. Что ж, это отлично работает, но помимо того, что это ОО-решение, кажется, что использование
with
— это то, что заставляет его работать должным образом. Можете ли вы объяснить, что с помощьюwith
…as writer
это не просто сказатьwriter =
, как я сделал в своем коде?2. @Tom.to будьте честны, я — ростовщик. Я просто использую использование по умолчанию
ExelWriter
, как в pandas.pydata.org/pandas-docs/stable/reference/api /…