2017-06-14 5 views
-1

Ich bin neu in Python und arbeite an einem Projekt, für das ich Hilfe nutzen könnte. Also versuche ich eine vorhandene Excel-Arbeitsmappe zu modifizieren, um Bestandsdaten zu vergleichen. Zum Glück gab es ein Programm online, das alle Daten, die ich brauche, abgerufen und ich war erfolgreich in der Lage, die Daten zu ziehen und die Daten in eine neue Excel-Datei schreiben. Ziel ist es jedoch, die Daten zu ziehen und in eine bestehende Excel-Datei zu übernehmen. Außerdem muss ich die Zellenwerte in der vorhandenen Datei überschreiben. Ich glaube, dass xlwings in der Lage ist, dies zu tun, und ich denke, dass mein Code auf dem richtigen Weg ist, aber ich stieß auf einen unerwarteten Fehler. Der Fehler, den ich erhalte, ist:Daten in eine vorhandene Arbeitsmappe mit Python überschreiben

Ich fragte mich, ob jemand wusste, warum dieser Fehler aufkam? Kann jemand es auch reparieren? Ist es reparierbar? Ist mein Code falsch? Jede Hilfe oder Anleitung wird geschätzt. Vielen Dank.

import good_morning as gm 
import pandas as pd 
import xlwings as xw 

#import income statement, balance sheet, and cash flow of AAPL 
fd = gm.FinancialsDownloader() 
fd_frames = fd.download('AAPL') 

#Creates a DataFrame for only the balance sheet 
df1 = pd.DataFrame(list(fd_frames.values())[0]) 

#connects to workbook I want to modify 
wb = xw.Book(r'C:\Users\vince\Project\Spreadsheet.xlsm') 

#sheet I would like to modify 
sht = wb.sheets[1] 

#modifies & overwrites values in my spreadsheet(this is where I get the type_error) 
sht.range('M6').value = df1 

Datentypen:

type(fd_frames) 
>>> <class 'dict'> 
fd_frames.values())[0].info() 
>>> <class 'pandas.core.frame.DataFrame'> 
RangeIndex: 22 entries, 0 to 21 
Data columns (total 8 columns): 
parent_index 22 non-null int64 
title 22 non-null object 
2012 19 non-null float64 
2013 20 non-null float64 
2014 20 non-null float64 
2015 20 non-null float64 
2016 20 non-null float64 
2017 20 non-null float64 
dtypes: float64(6), int64(1), object(1) 
memory usage: 1.5+ KB 
+0

Mögliche doppelte von [Schreiben und Ändern einer vorhandenen Arbeitsmappe mit Python] (https://stackoverflow.com/questions/44489950/writing-and-modifying-an-existing-workbo ok-using-python) –

+0

wie hilft pandas.DataFrame.append? Ich habe den Datenrahmen, den ich möchte. Ich habe Probleme beim Überschreiben vorhandener Daten aus meiner Excel-Datei mit dem Datenrahmen, den ich habe. Ich bin immer noch verwirrt, wie ich die Daten zu einer vorhandenen Arbeitsmappe bekomme – vdub32

+0

Ich glaube nicht, dass ich eine vorhandene Arbeitsmappe mit diesen Funktionen aktualisieren kann. Ich habe online gesucht und glaube nicht, dass es mit diesen Funktionen möglich ist. Es ist schwierig, eine Funktion zu finden, die einen bestehenden Arbeitsplatz verändert und die Daten darin ersetzt. Vielen Dank für Ihre Hilfe und Vorschläge. – vdub32

Antwort

0

Comments: You have a Dict of pandas.DataFrame .

Auswählen von einem Dict list(fd_frames.values())[0] Verwendung führt zu unberechenbar Ergebnisse. Zeigen Sie die Schlüssel des Dict und wählen Sie das Interesse aus Verwendung dieser Key, zB:

print(fd_frames.keys()) 
>>> dict_keys(['key_1', 'key_2', 'key_n'] 
df_2 = fd_frames['key_2'] 

Neben diesem Ihre weder der Dimension in pandas.DataFrame überein M6:M30 = 25. Es gibt nur 8 Spalten mit 20 Werte. Daher müssen Sie Ihren Arbeitsblattbereich an 20 Zeilen ausrichten. Um Spalte 2017 zu dem Arbeitsblatt zu schreiben, z.B .:

wb['M6:M25'] = df_2['2017'].values 

Note: I have updated the code below to accept numpy.ndarray also.


Question: ... the goal is to pull the data and put it into an existing excel file

-Update eine Arbeitsmappe Arbeitsblatt Bereich mit Listenwerte.
Verwendung: OpenPyXL: A Python library to read/write Excel 2010 xlsx/xlsm files

Note: Observe how the List Values have to be arranged!
param values: List: *[row 1(col1, ... ,coln), ..., row n(col1, ... ,coln)]`

from openpyxl import Workbook, load_workbook 

class UpdateWorkbook(object): 
    def __init__(self, fname, worksheet=0): 
     self.fname = fname 
     self.wb = load_workbook(fname) 
     self.ws = self.wb.worksheets[worksheet] 

    def save(self): 
     self.wb.save(self.fname) 

    def __setitem__(self, _range, values): 
     """ 
     Assign Values to a Worksheet Range 
     :param _range: String e.g ['M6:M30'] 
     :param values: List: [row 1(col1, ... ,coln), ..., row n(col1, ... ,coln)] 
     :return: None 
     """ 

     def _gen_value(): 
      for value in values: 
       yield value 

      if not isinstance(values, (list, numpy.ndarray)): 
       raise ValueError('Values Type Error: Values have to be "list": values={}'. 
            format(type(values))) 
      if isinstance(values, numpy.ndarray) and values.ndim > 1: 
       raise ValueError('Values Type Error: Values of Type numpy.ndarray must have ndim=1; values.ndim={}'. 
            format(values.ndim)) 

     from openpyxl.utils import range_boundaries 
     min_col, min_row, max_col, max_row = range_boundaries(_range) 
     cols = ((max_col - min_col)+1) 
     rows = ((max_row - min_row)+1) 
     if cols * rows != len(values): 
      raise ValueError('Number of List Values:{} does not match Range({}):{}'. 
          format(len(values), _range, cols * rows)) 

     value = _gen_value() 
     for row_cells in self.ws.iter_rows(min_col=min_col, min_row=min_row, 
              max_col=max_col, max_row=max_row): 
      for cell in row_cells: 
       cell.value = value.__next__() 

Usage

wb = UpdateWorkbook(r'C:\Users\vince\Project\Spreadsheet.xlsx', worksheet=1) 
df_2 = fd_frames['key_2'] 
wb['M6:M25'] = df_2['2017'].values 
wb.save() 

mit Python getestet: 3.4.2 - openpyxl: 2.4.1 - Libreoffice: 4.3.3.2

+0

Wenn ich diesen Code verwende, kann er Daten in eine vorhandene Arbeitsmappendatei einfügen. Es überschreibt jedoch die gesamte Arbeitsmappe.Es tut mir leid, dass ich nicht sehr klar war, aber ich möchte nur bestimmte Zellen in der vorhandenen Arbeitsmappe überschreiben und nicht alle Daten aus der Arbeitsmappe entfernen. Weißt du, ob das möglich ist? Ersetzen bestimmter Zellen durch den gewünschten Panda-Datenrahmen? Zum Beispiel würde ich die Zellen M6 bis M30 in einem Blatt namens Daten mit dem Datenrahmen ersetzen wollen. – vdub32

+0

Ja, genau das möchte ich tun, ohne die vorhandenen Daten in dieser Tabelle zu löschen oder zu löschen. Ich danke dir sehr! – vdub32

+0

Danke für den tollen Code! Ich stieß immer noch auf einen unerwarteten Fehler, den ich nicht verstehe. Aus irgendeinem Grund gibt es mir einen Wert Fehler. Die Fehlerzustände: ValueError: Werte Typ Fehler: Werte müssen "list" sein: values ​​= . Das macht für mich keinen Sinn, da wir den Datenrahmen in eine Liste konvertieren, aber ich könnte es falsch sehen. Danke für all deine Hilfe. Wenn Sie mir mehr Ratschläge geben könnten, würde ich es sehr schätzen! Nochmals vielen Dank – vdub32

Verwandte Themen