Wie speichere ich mit Pandas ein neues Blatt in einer vorhandenen Excel-Datei?

85

Ich möchte Excel-Dateien verwenden, um mit Python erstellte Daten zu speichern. Mein Problem ist, dass ich einer vorhandenen Excel-Datei keine Blätter hinzufügen kann. Hier schlage ich einen Beispielcode vor, mit dem Sie arbeiten können, um dieses Problem zu lösen

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

Dieser Code speichert zwei DataFrames auf zwei Blättern mit den Namen "x1" bzw. "x2". Wenn ich zwei neue DataFrames erstelle und versuche, mit demselben Code zwei neue Blätter hinzuzufügen, 'x3' und 'x4', gehen die ursprünglichen Daten verloren.

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

Ich möchte eine Excel-Datei mit vier Blättern: 'x1', 'x2', 'x3', 'x4'. Ich weiß, dass 'xlsxwriter' nicht die einzige "Engine" ist, es gibt 'openpyxl'. Ich habe auch gesehen, dass es bereits andere Leute gibt, die über dieses Problem geschrieben haben, aber ich kann immer noch nicht verstehen, wie das geht.

Hier ein Code aus diesem Link

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

Sie sagen, dass es funktioniert, aber es ist schwer herauszufinden, wie. Ich verstehe nicht, was "ws.title", "ws" und "dict" in diesem Zusammenhang sind.

Wie können Sie "x1" und "x2" am besten speichern, dann die Datei schließen, erneut öffnen und "x3" und "x4" hinzufügen?

Stefano Fedele
quelle

Antworten:

114

Vielen Dank. Ich glaube, dass ein vollständiges Beispiel für alle anderen gut sein könnte, die das gleiche Problem haben:

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

Hier generiere ich eine Excel-Datei, nach meinem Verständnis spielt es keine Rolle, ob sie über die "xslxwriter" - oder die "openpyxl" -Engine generiert wird.

Wenn ich dann schreiben möchte, ohne die Originaldaten zu verlieren

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

Dieser Code macht den Job!

Stefano Fedele
quelle
Irgendeine Idee, warum, wenn ich das versuche, ich Folgendes bekomme: ValueError: Kein Excel-Writer 'Sales Leads Calculations.xlsx'?
Bernando_vialli
1
Ja, dies fügt dem Excel das Blatt hinzu, ohne die bereits vorhandenen Blätter zu löschen. Vielen Dank!
Nikhil VJ
2
Wie behalte ich beim Speichern der Excel-Datei die vorhandenen Excel-Blattformate bei?
Vineesh TP
3
Wenn jemand dies liest und sich fragt, wie ein vorhandenes Blatt mit demselben Namen überschrieben werden kann, anstatt das neue writer.sheets = dict((ws.title, ws) for ws in book.worksheets)writer.book = book
umzubenennen
1
@Stefano Fedele Kannst du die gleiche Aktualisierung des vorhandenen Excel mit 'xlsxwriter' anstelle von 'openpyxl' durchführen?
M Nikesh
15

In dem von Ihnen freigegebenen Beispiel laden Sie die vorhandene Datei in bookund legen den writer.bookWert fest book. In der Zeile writer.sheets = dict((ws.title, ws) for ws in book.worksheets)greifen Sie auf jedes Blatt in der Arbeitsmappe als zu ws. Der Blatttitel lautet dann, wssodass Sie ein Wörterbuch mit {sheet_titles: sheet}Schlüssel-Wert-Paaren erstellen . Dieses Wörterbuch wird dann auf writer.sheets gesetzt. Im Wesentlichen laden diese Schritte nur die vorhandenen Daten von 'Masterfile.xlsx'und füllen Ihren Writer damit.

Angenommen, Sie haben bereits eine Datei mit x1und x2als Blatt. Sie können den Beispielcode verwenden, um die Datei zu laden, und dann so etwas tun, um x3und hinzuzufügen 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()

Das sollte tun, wonach Sie suchen.

Grr
quelle
Irgendeine Idee, warum, wenn ich das versuche, ich Folgendes bekomme: ValueError: Kein Excel-Writer 'Sales Leads Calculations.xlsx'?
Bernando_vialli
18
Dadurch werden die bereits vorhandenen Blätter gelöscht.
Nikhil VJ
13

Ein einfaches Beispiel für das gleichzeitige Schreiben mehrerer Daten. Und auch, wenn Sie Daten an ein Blatt in einer geschriebenen Excel-Datei (geschlossene Excel-Datei) anhängen möchten.

Wenn Sie zum ersten Mal an ein Excel schreiben. (Schreiben von "df1" und "df2" in "1st_sheet" und "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()    

Nachdem Sie Ihr Excel geschlossen haben, aber Daten an dieselbe Excel-Datei, aber an ein anderes Blatt "anhängen" möchten, sagen wir "df3" zum Blattnamen "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()     

Beachten Sie, dass das Excel-Format nicht xls sein darf. Sie können xlsx one verwenden.

Wong Tat Yau
quelle
1
Ich sehe nicht, was diese Antwort hinzufügt. Tatsächlich erfordert die wiederholte Verwendung eines solchen Kontextmanagers viel mehr E / A.
Charlie Clark
8

Ich würde Ihnen dringend empfehlen, direkt mit openpyxl zu arbeiten, da es jetzt Pandas DataFrames unterstützt .

So können Sie sich auf den relevanten Excel- und Pandas-Code konzentrieren.

Charlie Clark
quelle
3
Es wäre wirklich hilfreich, wenn Sie etwas mehr „Pandas“ Beispiele ähnlich hinzufügen könnte dieser
MAXU
Ich arbeite nicht viel mit Pandas selbst, daher kann ich nicht so viele Beispiele nennen, würde aber Verbesserungen der Dokumentation begrüßen.
Charlie Clark
4

Zum Erstellen einer neuen Datei

x1 = np.random.randn(100, 2)
df1 = pd.DataFrame(x1)
with pd.ExcelWriter('sample.xlsx') as writer:  
    df1.to_excel(writer, sheet_name='x1')

Verwenden Sie zum Anhängen an die Datei das Argument mode='a'in pd.ExcelWriter.

x2 = np.random.randn(100, 2)
df2 = pd.DataFrame(x2)
with pd.ExcelWriter('sample.xlsx', engine='openpyxl', mode='a') as writer:  
    df2.to_excel(writer, sheet_name='x2')

Standard ist mode ='w'. Siehe Dokumentation .

Pulkit Khandelwal
quelle
3

Dies ist ohne Verwendung von ExcelWriter und Verwendung von Tools in openpyxl möglich. Dies kann das Hinzufügen von Schriftarten zum neuen Blatt erheblich vereinfachen openpyxl.styles

import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils.dataframe import dataframe_to_rows

#Location of original excel sheet
fileLocation =r'C:\workspace\data.xlsx'

#Location of new file which can be the same as original file
writeLocation=r'C:\workspace\dataNew.xlsx'

data = {'Name':['Tom','Paul','Jeremy'],'Age':[32,43,34],'Salary':[20000,34000,32000]}

#The dataframe you want to add
df = pd.DataFrame(data)

#Load existing sheet as it is
book = load_workbook(fileLocation)
#create a new sheet
sheet = book.create_sheet("Sheet Name")

#Load dataframe into new sheet
for row in dataframe_to_rows(df, index=False, header=True):
    sheet.append(row)

#Save the modified excel at desired location    
book.save(writeLocation)
Jis Mathew
quelle
Dies ist eine nette Lösung, aber ich bin mir nicht sicher, ob es auch eine Implikation ist. Meinst du, du kannst es nicht damit machen ExcelWriteroder musst es einfach nicht?
MattSom
Sie können es mit Excelwriter tun, aber ich finde es einfacher, wenn Sie nur openpyxl verwenden.
Jis Mathew
2

Sie können vorhandene Blätter Ihrer Interessen, z. B. 'x1', 'x2', in den Speicher lesen und zurückschreiben, bevor Sie weitere neue Blätter hinzufügen (beachten Sie, dass die Blätter in einer Datei und die Blätter im Speicher zwei verschiedene sind Dinge, wenn Sie sie nicht lesen, gehen sie verloren). Dieser Ansatz verwendet nur 'xlsxwriter', kein 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()

Wenn Sie alle vorhandenen Blätter beibehalten möchten, können Sie den obigen Code zwischen Anfang und Ende durch Folgendes ersetzen:

# 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)
Jonathan L.
quelle
1
#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')
nileshk611
quelle
1
Ich verfolge nicht, wie dies mit der Frage zusammenhängt, außer dass es um Excel geht.
Artog
Ich habe daran gearbeitet, eine vollständige Lösung zum Lesen und Schreiben in vorhandene Arbeitsmappen zu finden, konnte diese jedoch nicht finden. Hier habe ich einen Hinweis gefunden, wie man in eine vorhandene Arbeitsmappe schreibt, also habe ich mir überlegt, eine vollständige Lösung für mein Problem zu finden. Hoffe es ist klar.
Nileshk611
0

Ein anderer ziemlich einfacher Weg, dies zu tun, besteht darin, eine Methode wie diese zu erstellen:

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)

Die Idee hier ist, die Arbeitsmappe unter path_to_file zu laden, falls vorhanden, und dann den data_frame als neues Blatt mit sheet_name anzuhängen . Wenn die Arbeitsmappe nicht vorhanden ist, wird sie erstellt. Es scheint, dass weder openpyxl noch xlsxwriter anhängen. Wie im obigen Beispiel von @Stefano müssen Sie also wirklich laden und dann neu schreiben, um sie anzuhängen.

MrMajestyk
quelle