Fehler beim Lesen von Daten aus EXCEL und Schreiben in ein anderes Workbook

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
stef_kfb
User
Beiträge: 1
Registriert: Sonntag 5. Mai 2019, 13:10

Sonntag 5. Mai 2019, 17:50

Hallo zusammen,
ich bin Python Neuling und möchte gerne Zellen aus einer Excel-Datei auslesen und in ein anderen Worksheet wieder einlesen.
In einer Spalte der Tabelle befinden sich Datumsfelder (Format; 2018-01-01 00:00).
Ich lese die Daten mit einem np.empty-Array ein und möchte die Elemente des Arrays wieder in die Zellen eines anderen Worksheets auslesen.Dabei ensteht bei der Übertragung der Datumsfelder ein Fehler. Excel ist offensichtlich nicht in der Lage das Format wieder umzuwandeln. Mir ist klar, dass es sich um ein Formatfehler handelt, aber ich habe keine Idee wie das Problem zu lösen ist.
Wenn jemand einen Tipp hat, wäre ich dankbar.
Beste Grüße

Code: Alles auswählen

import openpyxl
import os
import xlsxwriter
import pandas as pd
import numpy as np
import datetime

path1='e:\Quelldaten_Stromkonktrakte EEX Baseload Year_KOS/PhelixDEPowerFuturesHistory_2018.xlsx'
wb=openpyxl.load_workbook(path1)
sheet=wb['DEBY']

daten_ein = pd.ExcelFile(path1)
df=daten_ein.parse('DEBY')
zellenanzahl_ein=df.shape[0]

# Anlegen von arrays um Zellendaten einzulesen und zu kopieren
arr2018_Handelstag= np.empty(zellenanzahl_ein, dtype='str')
arr2018_Lieferperiode=np.empty(zellenanzahl_ein)
arr2018_Settlementpreis=np.empty(zellenanzahl_ein)

for i in range (1,zellenanzahl_ein-1):
    arr2018_Handelstag[i]= sheet.cell(row=i+3,column=1).value 
    arr2018_Lieferperiode[i]=sheet.cell(row=i+3,column=3).value
    arr2018_Settlementpreis[i]=sheet.cell(row=i+3,column=11).value    
    

path2='e:/test3.xlsx'
wb1=openpyxl.load_workbook(path2)
sheet1=wb1['ausgabe']
daten_aus = pd.ExcelFile(path2)
df1=daten_aus.parse('ausgabe')
if df1.shape[0]==0:
     z=df1.shape[0]+1
else:
     z=df1.shape[0]+2

s=5

for i in range(1,zellenanzahl_ein-1):
        sheet1.cell(s,4).value =arr2018_Settlementpreis[i]
        sheet1.cell(s,3).value=arr2018_Lieferperiode[i]
        sheet1.cell(s,2).value=(arr2018_Handelstag[i])
        s+=1
print("Programm abgeschlossen")       
wb1.save(path2)
wb1.close
Fehlermeldung:
File "C:\Users\Stefan_Sony\Anaconda3\lib\site-packages\openpyxl\cell\cell.py", line 218, in _bind_value
raise ValueError("Cannot convert {0!r} to Excel".format(value))

ValueError: Cannot convert '2' to Excel
Benutzeravatar
__blackjack__
User
Beiträge: 3084
Registriert: Samstag 2. Juni 2018, 10:21

Sonntag 5. Mai 2019, 17:58

@stef_kfb: Bitte den gesamten Traceback zeigen, so dass man auch sehen kann *wo* die Ausnahme in *Deinem* Code ihren Ursprung hat.

Edit: Was soll denn der Unsinn mit Pandas und Numpy? Du lädst die gleiche Datei auch noch mal mit Pandas nur um die Anzahl der Zeilen zu ermitteln? Und warum die Numpy-Arrays statt Python-Listen? Das macht den Code nur umständlich und unpythonisch, weil Du von Numpy gar nicht wirklich etwas benutzt.
“In computing, invariants are ephemeral.” – Alan J. Perlis
Benutzeravatar
__blackjack__
User
Beiträge: 3084
Registriert: Samstag 2. Juni 2018, 10:21

Freitag 10. Mai 2019, 15:20

@stef_kfb: `datetime`, `os`, und `xlsxwriter` werden importiert, aber nicht benutzt.

Namen werden in Python klein_mit_unterstrichen geschreiben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).

Wenn man anfängt Nummern an Namen anzuhängen, will man entweder bessere Namen verwenden, oder gar keine Einzelnamen, sondern eine Datenstruktur. Oft eine Liste. Im vorliegenden Quelltext denke ich es sind einfach schlechte Namen. `path1` und `path2` sagen dem Leser nichts über die Bedeutung der Werte hinter diesen Namen – genau dafür sind Namen aber gedacht.

Wie schon gesagt macht es wenig Sinn die Dateien mit `openpyxl` *und* `pandas` zu lesen. Bei der Ausgabedatei ist es doppelt sinnlos, weil der daraus gewonnene Wert `z` dann gar nicht verwendet wird.

`zellenanzahl_ein` würde besser `zeilenanzahl` heissen.

Die Numpy-Arrays machen keinen Sinn. Statt ”leere” Arrays zu erzeugen und die dann mit später per Indexzugriff mit den tatsächlichen Daten zu bestücken, verwendet man in Python Listen die leer starten und an die dann die Werte angehängt werden.

Der `arr2018_*`-Präfix kann weg.

Und es wäre leichter wenn man die Werte nicht in drei ”parallelen” Listen speichert, sondern die Elemente zum Beispiel zu einem Tupel zusammenfasst und in *einer* Liste speichert.

Man kann in Python direkt über die Elemente von Sequenzen wie Listen (aber auch Numpy-Arrays) iterieren, ohne den Umweg über einen Laufindex. Falls man zusätzlich zu den Elementen eine laufende Zahl benötigt, gibt es die `enumerate()`-Funktion.

Um Zuweisungen aussergalb von Argumentlisten und um binäre Operatoren erhöhen Lehrzeichen die Lesbarkeit.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import openpyxl

SOURCE_FILENAME = (
    'e:/Quelldaten_Stromkonktrakte EEX Baseload Year_KOS/'
        'PhelixDEPowerFuturesHistory_2018.xlsx'
)
SOURCE_SHEET_NAME = 'DEBY'
SOURCE_COLUMN_NUMBERS = [1, 3, 11]

TARGET_FILENAME = 'e:/test3.xlsx'
TARGET_SHEET_NAME = 'ausgabe'
TARGET_COLUMN_NUMBERS = [2, 3, 4]


def main():
    source_workbook = openpyxl.load_workbook(SOURCE_FILENAME)
    source_sheet = source_workbook[SOURCE_SHEET_NAME]
    data = list()
    for row_number in range(4, source_sheet.max_row + 1):
        data.append(
            tuple(
                source_sheet.cell(row_number, column_number).value
                for column_number in SOURCE_COLUMN_NUMBERS
            )
        )

    target_workbook = openpyxl.load_workbook(TARGET_FILENAME)
    target_sheet = target_workbook[TARGET_SHEET_NAME]
    for row_number, values in enumerate(data, 5):
        for column_number, value in zip(TARGET_COLUMN_NUMBERS, values):
            target_sheet.cell(row_number, column_number).value = value
    target_workbook.save(TARGET_FILENAME)
    
    print('Programm abgeschlossen')


if __name__ == '__main__':
    main()
“In computing, invariants are ephemeral.” – Alan J. Perlis
Antworten