Как сохранить новый лист в существующем файле excel, используя Pandas?
Я хочу использовать файлы excel для хранения данных, разработанных с помощью python. Моя проблема в том, что я не могу добавить листы в существующий файл excel. Здесь я предлагаю пример кода для работы, чтобы решить эту проблему.
import pandas as pd
import numpy as np
path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"
x1 = np.random.randn(100, 2)
df1 = pd.DataFrame(x1)
x2 = np.random.randn(100, 2)
df2 = pd.DataFrame(x2)
writer = pd.ExcelWriter(path, engine = 'xlsxwriter')
df1.to_excel(writer, sheet_name = 'x1')
df2.to_excel(writer, sheet_name = 'x2')
writer.save()
writer.close()
Этот код сохраняет два DataFrames на два листа с именами "x1" и "x2" соответственно. Если я создаю два новых DataFrames и попытаюсь использовать один и тот же код для добавления двух новых листов "x3" и "x4", исходные данные будут потеряны.
import pandas as pd
import numpy as np
path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"
x3 = np.random.randn(100, 2)
df3 = pd.DataFrame(x3)
x4 = np.random.randn(100, 2)
df4 = pd.DataFrame(x4)
writer = pd.ExcelWriter(path, engine = 'xlsxwriter')
df3.to_excel(writer, sheet_name = 'x3')
df4.to_excel(writer, sheet_name = 'x4')
writer.save()
writer.close()
Мне нужен файл excel с четырьмя листами: 'x1', 'x2', 'x3', 'x4'.
Я знаю, что "xlsxwriter" - не единственный "движок", есть "openpyxl". Я также видел, что есть уже другие люди, которые писали об этой проблеме, но все же я не могу понять, как это сделать.
Вот код, взятый из этой ссылки
import pandas
from openpyxl import load_workbook
book = load_workbook('Masterfile.xlsx')
writer = pandas.ExcelWriter('Masterfile.xlsx', engine='openpyxl')
writer.book = book
writer.sheets = dict((ws.title, ws) for ws in book.worksheets)
data_filtered.to_excel(writer, "Main", cols=['Diff1', 'Diff2'])
writer.save()
Говорят, что это работает, но трудно понять, как это сделать. Я не понимаю, что в этом контексте "ws.title", "ws" и "dict".
Каков наилучший способ сохранить "x1" и "x2", затем закройте файл, откройте его снова и добавьте "x3" и "x4"?
Ответы
Ответ 1
Спасибо. Я считаю, что полный пример может быть полезен для всех, кто имеет такую же проблему:
import pandas as pd
import numpy as np
path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"
x1 = np.random.randn(100, 2)
df1 = pd.DataFrame(x1)
x2 = np.random.randn(100, 2)
df2 = pd.DataFrame(x2)
writer = pd.ExcelWriter(path, engine = 'xlsxwriter')
df1.to_excel(writer, sheet_name = 'x1')
df2.to_excel(writer, sheet_name = 'x2')
writer.save()
writer.close()
Здесь я создаю файл Excel, из моего понимания не имеет значения, генерируется ли он с помощью механизма "xslxwriter" или "openpyxl".
Когда я хочу писать без потери исходных данных, то
import pandas as pd
import numpy as np
from openpyxl import load_workbook
path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"
book = load_workbook(path)
writer = pd.ExcelWriter(path, engine = 'openpyxl')
writer.book = book
x3 = np.random.randn(100, 2)
df3 = pd.DataFrame(x3)
x4 = np.random.randn(100, 2)
df4 = pd.DataFrame(x4)
df3.to_excel(writer, sheet_name = 'x3')
df4.to_excel(writer, sheet_name = 'x4')
writer.save()
writer.close()
этот код делает работу!
Ответ 2
В приведенном вами примере вы загружаете существующий файл в book
и устанавливаете значение writer.book
равным book
. В строке writer.sheets = dict((ws.title, ws) for ws in book.worksheets)
вы получаете доступ к каждому листу в книге как ws
. Заголовок листа тогда ws
, поэтому вы создаете словарь {sheet_titles: sheet}
ключей, пар значений. Затем этот словарь устанавливается в файле writer.sheets. По сути, эти шаги просто загружают существующие данные из 'Masterfile.xlsx'
и заполняют их автором.
Теперь предположим, что у вас уже есть файл с x1
и x2
как листы. Вы можете использовать пример кода для загрузки файла, а затем можете сделать что-то вроде этого, чтобы добавить x3
и x4
.
path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"
writer = pd.ExcelWriter(path, engine='openpyxl')
df3.to_excel(writer, 'x3', index=False)
df4.to_excel(writer, 'x4', index=False)
writer.save()
Это должно делать то, что вы ищете.
Ответ 3
Простой пример для написания нескольких данных, которые нужно перенести за раз. А также, когда вы хотите добавить данные к листу в написанном файле excel (закрытый файл excel).
Когда вы впервые пишете Excel. (Запись "df1" и "df2" в "1st_sheet" и "2nd_sheet" )
import pandas as pd
from openpyxl import load_workbook
df1 = pd.DataFrame([[1],[1]], columns=['a'])
df2 = pd.DataFrame([[2],[2]], columns=['b'])
df3 = pd.DataFrame([[3],[3]], columns=['c'])
excel_dir = "my/excel/dir"
with pd.ExcelWriter(excel_dir, engine='xlsxwriter') as writer:
df1.to_excel(writer, '1st_sheet')
df2.to_excel(writer, '2nd_sheet')
writer.save()
После того, как вы закроете свое преимущество, но вы хотите "добавить" данные в один файл Excel, но еще один лист, скажем "df3" на имя листа "3rd_sheet".
book = load_workbook(excel_dir)
with pd.ExcelWriter(excel_dir, engine='openpyxl') as writer:
writer.book = book
writer.sheets = dict((ws.title, ws) for ws in book.worksheets)
## Your dataframe to append.
df3.to_excel(writer, '3rd_sheet')
writer.save()
Следует отметить, что формат excel не должен быть xls, вы можете использовать xlsx one.
Ответ 4
Я настоятельно рекомендую вам работать с openpyxl, так как теперь он поддерживает Pandas DataFrames.
Это позволяет сосредоточиться на соответствующем Excel и Pandas.
Ответ 5
Вы можете прочитать существующие листы ваших интересов, например, "x1", "x2", в память и "записать" их перед добавлением новых листов (имейте в виду, что листы в файле и листы в памяти - это два разных вещи, если вы их не прочитаете, они будут потеряны). Этот подход использует только 'xlsxwriter', openpyxl не задействован.
import pandas as pd
import numpy as np
path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"
# begin <== read selected sheets and write them back
df1 = pd.read_excel(path, sheet_name='x1', index_col=0) # or sheet_name=0
df2 = pd.read_excel(path, sheet_name='x2', index_col=0) # or sheet_name=1
writer = pd.ExcelWriter(path, engine='xlsxwriter')
df1.to_excel(writer, sheet_name='x1')
df2.to_excel(writer, sheet_name='x2')
# end ==>
# now create more new sheets
x3 = np.random.randn(100, 2)
df3 = pd.DataFrame(x3)
x4 = np.random.randn(100, 2)
df4 = pd.DataFrame(x4)
df3.to_excel(writer, sheet_name='x3')
df4.to_excel(writer, sheet_name='x4')
writer.save()
writer.close()
Если вы хотите сохранить все существующие листы, вы можете заменить приведенный выше код между началом и концом:
# read all existing sheets and write them back
writer = pd.ExcelWriter(path, engine='xlsxwriter')
xlsx = pd.ExcelFile(path)
for sheet in xlsx.sheet_names:
df = xlsx.parse(sheet_name=sheet, index_col=0)
df.to_excel(writer, sheet_name=sheet)
Ответ 6
#This program is to read from excel workbook to fetch only the URL domain names and write to the existing excel workbook in a different sheet..
#Developer - Nilesh K
import pandas as pd
from openpyxl import load_workbook #for writting to the existing workbook
df = pd.read_excel("urlsearch_test.xlsx")
#You can use the below for the relative path.
# r"C:\Users\xyz\Desktop\Python\
l = [] #To make a list in for loop
#begin
#loop starts here for fetching http from a string and iterate thru the entire sheet. You can have your own logic here.
for index, row in df.iterrows():
try:
str = (row['TEXT']) #string to read and iterate
y = (index)
str_pos = str.index('http') #fetched the index position for http
str_pos1 = str.index('/', str.index('/')+2) #fetched the second 3rd position of / starting from http
str_op = str[str_pos:str_pos1] #Substring the domain name
l.append(str_op) #append the list with domain names
#Error handling to skip the error rows and continue.
except ValueError:
print('Error!')
print(l)
l = list(dict.fromkeys(l)) #Keep distinct values, you can comment this line to get all the values
df1 = pd.DataFrame(l,columns=['URL']) #Create dataframe using the list
#end
#Write using openpyxl so it can be written to same workbook
book = load_workbook('urlsearch_test.xlsx')
writer = pd.ExcelWriter('urlsearch_test.xlsx',engine = 'openpyxl')
writer.book = book
df1.to_excel(writer,sheet_name = 'Sheet3')
writer.save()
writer.close()
#The below can be used to write to a different workbook without using openpyxl
#df1.to_excel(r"C:\Users\xyz\Desktop\Python\urlsearch1_test.xlsx",index='false',sheet_name='sheet1')
Ответ 7
Другой довольно простой способ сделать это - создать такой метод:
def _write_frame_to_new_sheet(path_to_file=None, sheet_name='sheet', data_frame=None):
book = None
try:
book = load_workbook(path_to_file)
except Exception:
logging.debug('Creating new workbook at %s', path_to_file)
with pd.ExcelWriter(path_to_file, engine='openpyxl') as writer:
if book is not None:
writer.book = book
data_frame.to_excel(writer, sheet_name, index=False)
Идея заключается в том, чтобы загрузить книгу в path_to_file, если она существует, а затем добавить data_frame в качестве нового листа с имя_листа. Если рабочая книга не существует, она создается. Кажется, что ни openpyxl, ни xlsxwriter не добавляются, так что, как в примере с @Stefano выше, вам действительно нужно загрузить и затем переписать, чтобы добавить.