4
votes

Ajout de Pandas DataFrame à un document Excel existant

Par https://github.com/pandas-dev/ pandas / pull / 21251 / files / 09e5b456e1af5cde55f18f903ab90c761643b05a , nous devrions pouvoir ajouter des DataFrames aux nouvelles feuilles XLSX.

Sur la base de la documentation, j'ai essayé ce qui suit:

>>> import pandas as pd
>>>                
... d1 = pd.DataFrame({"A":['Bob','Joe', 'Mark'], 
...                "B":['5', '10', '20']})
>>> d2 = pd.DataFrame({"A":['Jeffrey','Ann', 'Sue'], 
...                "B":['1', '2', '3']})
>>> 
>>> # Create XLSX document for ticker
... writer = pd.ExcelWriter('test.xlsx',engine='openpyxl')
>>> d1.to_excel(writer,sheet_name='d1')
>>> writer.save()
>>> 
>>> writer = pd.ExcelWriter('test.xlsx',engine='openpyxl', mode='a')
>>> d2.to_excel(writer,sheet_name='d2')
>>> writer.save()
>>> 
>>> pd.__version__
'0.23.4'     # Just updated this per a comment
>>> 
>>> 


6 commentaires

Copie possible de Comment écrire à un fichier Excel existant sans écraser les données (à l'aide de pandas)?


Désolé, un peu trop rapide pour marquer comme duplicata. Cela a été introduit dans la version pandas 0.23.1 , vous devez donc effectuer une mise à niveau.


Merci, j'ai mis à jour par votre suggestion. J'utilisais "pip3 install pandas" au lieu d'ajouter "--upgrade" donc je pensais avoir la dernière version. Selon votre suggestion, j'ai mis à jour mais j'obtiens toujours le même résultat.


En outre, l'autre référencé << a href = "https://stackoverflow.com/questions/20219254/how-to-write-to-an-existing-excel-file-without-overwriting-data-using-pandas" title = "comment écrire dans un fichier Excel existant sans écraser les données à l'aide de pandas"> stackoverflow.com/questions/20219254/... > est pour la fonction 'df.to_excel ()', pas 'pd.ExcelWriter'.


Exécutez-vous ceci sur un REPL? Assurez-vous de redémarrer votre shell car le module pandas est chargé en mémoire avec l'ancienne version.


Sur la base de ma recherche, je suppose que "REPL" est en train de taper directement dans le terminal. Donc, comme je suis sur un Mac, je suis connecté au terminal et j'ai entré les commandes une par une. J'ai fait deux choses selon votre recommandation (1) fermé toutes les fenêtres du terminal, puis redémarré le terminal; (2) Ran le script via le terminal, c'est-à-dire "python3 test.py". Les résultats des deux cas sont malheureusement les mêmes.


3 Réponses :


7
votes

Vous pouvez utiliser with:

d1 = pd.DataFrame({"A":['Bob','Joe', 'Mark'], 
               "B":['5', '10', '20']})
d2 = pd.DataFrame({"A":['Jeffrey','Ann', 'Sue'], 
                "B":['1', '2', '3']})

writer = pd.ExcelWriter('atest.xlsx', engine='openpyxl', mode='w')
d1.to_excel(writer,sheet_name='d1')
writer.save()
writer.close()

writer = pd.ExcelWriter('atest.xlsx', engine='openpyxl', mode='a')
writer.book = load_workbook('atest.xlsx')
d2.to_excel(writer,sheet_name='d2')
writer.save()
writer.close()

update

Cela devrait fonctionner, notez simplement qu'un fichier vierge doit être créé avant . Vous pouvez simplement créer un fichier vide en utilisant python si vous le souhaitez. J'ai créé une boucle simple pour, d'une certaine manière, imiter l'essence de ce que vous essayez d'accomplir:

import pandas as pd
from openpyxl import load_workbook

d1 = pd.DataFrame({"A":['Bob','Joe', 'Mark'], 
               "B":['5', '10', '20']})
d2 = pd.DataFrame({"A":['Jeffrey','Ann', 'Sue'], 
                "B":['1', '2', '3']})

dfs = [d1,d2]

for i in range(len(dfs)):
    sheet = 'd'+str(i+1)
    data = dfs[i]
    writer = pd.ExcelWriter('atest.xlsx',engine='openpyxl', mode='a')
    writer.book = load_workbook('atest.xlsx') # here is the difference
    data.to_excel(writer,sheet_name=sheet)
    writer.save()
    writer.close()

ou voici le premier exemple modifié:

XXX


4 commentaires

J'ai essayé cela mais le résultat est comparable à xlsxwriter.readthedocs.io/example_pandas_multiple.html . C'est un moteur différent, mais le classeur n'est ouvert qu'une seule fois, puis les deux onglets sont écrits. J'ai besoin d'ouvrir / écrire / fermer puis ouvrir / écrire / fermer. J'ai essayé votre suggestion en mettant d1.to_excel () et d2.to_excel () dans des boucles séparées avec mais le résultat était un XLSX unique avec un seul onglet. J'ai également essayé votre suggestion mais avec le réglage mode = 'w' . Cela fonctionnait de la même manière que mode = 'a' .


@enter_display_name_here pourquoi avez-vous besoin d'ouvrir / écrire / fermer plusieurs fois?


Je suis en train de créer un dictionnaire extrêmement volumineux de DataFrames et j'aimerais écrire chaque DataFrame sous forme d'onglet au fur et à mesure de leur fin. Je détesterais avoir plus de 100 DataFrames, puis le programme rencontre un problème et rien n'est écrit. Fondamentalement, je suis en train de gratter 4 sites Web, de compiler différentes tables de données dans un seul DF, puis de répéter ce processus encore et encore. Je voudrais générer un onglet individuel par DF ​​au fur et à mesure du déroulement du programme.


Merci d'avoir pris le temps de mettre cela ensemble. Votre mise à jour est en fait la solution de contournement à ce qui a été fait avant l'ajout de mode = 'a' . Si vous vous référez à la ligne 1009 (ici:

J'ai envoyé un message sur GitHub et j'ai reçu une réponse des contributeurs (voir la partie en surbrillance ci-dessous). Il s'avère que cette fonctionnalité ne sera pas disponible avant le 0.24 donc elle n'est pas disponible dans 0.23.1 . FYI - J'ai téléchargé le RC et essayé avec succès l'option mode = 'a' . Cependant, il peut y avoir un bogue avec des classeurs qui n'existent pas; Je reçois FileNotFoundError: [Errno 2] Aucun fichier ou répertoire de ce type: 'test.xlsx' .

"cette fonctionnalité est publiée dans le cadre de la version 0.24 pour laquelle nous venons de publier une version candidate au cours des derniers jours. Vous pouvez essayer sur le RC ou ici sur master et si aucune des deux ne fonctionne, ouvrez un problème selon le guide de contribution, mais on ne s'attend pas à ce que cela fonctionne sur des versions antérieures à cela "


3 commentaires

avez-vous d'abord créé le fichier test.xlsx vierge


Oui, j'ai essayé ça et ça a marché. J'ai également revérifié leur code. Au début, je pensais qu'un nouveau classeur serait créé s'il n'en existait pas, mais je pense que c'est incorrect. Je pense que le code crée un nouveau classeur si mode = n'est pas 'a' , pas si un classeur n'existe pas.


Après avoir examiné le code qui est correct, un fichier n'est pas créé lorsque mode == 'a' ils utilisent simplement load_workbook , ce qui signifie que le fichier doit exister avant exécutant ExcelWriter avec le paramètre mode = 'a' si mode! = a alors ils créent un nouveau classeur: self.book = Classeur ()



0
votes

importer des pandas en tant que pd

writer = pd.ExcelWriter(wk_path + save_file)
# ....
# build sc_files DataFrame and save. sc_files includes
# a column called OS.

sc_file.to_excel(writer, sheet_name='test')

# build data frame of OS counts out of sc_file
counts_os = sc_file.OS.value_counts() 

# To append to 'test' sheet, use startcol=x1, startrow=y
# To append counts_OS to the end of the current 'test' sheet
y = len(sc_file)
y += 1
counts_os.to_excel(writer, sheet_name='test', 
    startcol=1, startrow=y)

# write counts_os to sheet test2 
counts_os.to_excel(writer, sheet_name='test2')
writer.save()
writer.close()


1 commentaires

Relisez simplement et voyez que j'ai répondu comment ajouter au même onglet, mais la question concerne plusieurs onglets. J'ai un programme similaire au vôtre qui écrit plusieurs onglets avec succès. Je ne spécifie pas engine = 'openpyxl' et je ne fais pas de writer.save () jusqu'à la toute fin du programme - dernière étape. Fonctionne bien que je puisse voir des limites si mes données étaient trop volumineuses.