Удаление и замена фрейма данных Pandas на листе Excel

#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 /…