Arbeiten mit Excel Dateiten beschleunigen

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Speedy
User
Beiträge: 11
Registriert: Mittwoch 4. September 2019, 11:29

Hallo zusammen,

aktuell versuche ich, meine Messdaten, die ich leider in Form von Excel Dateien bekomme, mit einem effizienten Programm zu bearbeiten.

Der Haken an der ganzen Geschichte ist, dass ich verschiedene Excel Workbooks (WB) bekomme. Z.B.
Die ersten 3 Sheets des erstens Workbooks sind 3 unterschiedliche Sheets mit verschiedenen Daten. Ab dem vieretn Sheet sind alle Sheets, egal wievieltes Workbook identisch. Ich habe festgestellt, dass es einfach viel zu lange dauert, diese Excel Sheets zu lesen. Und generell sieht mein Code furchtbar aus und ich wäre dankbar für jeden Tipp, um es "übersichtlicher" zu gestalten.

(Der Code im folgenden ist ein Ausschnitt, aber das ist eigentlich der "Kern-Code")

Code: Alles auswählen

import os, errno
#import platform
from xlrd import open_workbook
from xlrd import XL_CELL_TEXT, XL_CELL_NUMBER, XL_CELL_DATE, XL_CELL_BOOLEAN
import numpy as np
import pandas as pd
import re
import math
import matplotlib.pyplot as plt
import matplotlib
#matplotlib.use('GTK3Agg')
from matplotlib.cm import get_cmap
from matplotlib import colors as mcolors
from matplotlib.pyplot import cm
from matplotlib.font_manager import FontProperties
Und jetzt meine Funktion, wenn ich insgesamt 2 Excel Dateien für die selbe Messung habe:

Code: Alles auswählen

def two_workbooks():
    global C_3_wrt
    global U_3_wrt
    global t_hours
    global tot_cyc_1
    global cap_ch_1
    global cap_dch_1

    ## 3 Excel Workbooks were created
    excel_file = pd.ExcelFile(os.path.join(path_exc, barcode[b]))
    excel_file_1 = pd.ExcelFile(os.path.join(path_exc, barcode[b + 1])) # wenn ich mehr files habe, dann wächst dieserAbschnitt um +2, +3, +n.....
    
    #List with sheets names were generated
    worksheets = excel_file.sheet_names
    worksheets_1 = excel_file_1.sheet_names #auch hier, je mehr files, desto mehr sheets
    
    
    #First excel Workbooks contain 3 sheets in the beginning, all Detail_x_x_x containing sheet names were put into a list
    Detail_cont_sheet_list = [x for x in worksheets if re.search("Detail", x, re.IGNORECASE)]
    Detail_cont_sheet_list_1 = [x for x in worksheets_1 if re.search("Detail", x, re.IGNORECASE)]
    first_sheets = [x for x in worksheets if x not in Detail_cont_sheet_list] 
    
    ################################################################################################################################
    ################################################################################################################################
    #
    #Cycle_Sheet (second sheet) from first Workbook
    result_arr1 = pd.read_excel(excel_file, sheet_name = first_sheets[1]).to_numpy()
    
    # channel, tot_cyc:total cycle, cap_ch:capacity of charge(mAh), cap_dch:capacity of discharge(mAh), cyc_life(%)
    channel_1, tot_cyc_1, cap_ch_1, cap_dch_1, cyc_life_1 = result_arr1.T
    
    
    
    ##########################################
    
    #Statistik sheet (3rd sheet) from first workbook
    result_arr2 = pd.read_excel(excel_file, sheet_name = first_sheets[2]).to_numpy()
    
    #Channel,cyc_2:CyCle,	step_2:Step,	raw_step:Raw Step ID,	stat_2:Status, U_i:Start Voltage(V), U_e:End Voltage(V),
    #I_i=Start Current(mA), I_e:End Current(mA),C_2:CapaCity(mAh),	endure_t:Endure Time(h:min:s.ms), 
    #rel_t_2:Relative Time(h:min:s.ms),	 abs_t_2:Absolute Time, cap_disch:Discharge_Capacity(mAh), cap_ch_2:Charge_Capacity(mAh),	
    #cap_dch_2_2:Discharge_Capacity(mAh), nE_2:Net Engy_DChg(Wh), E_ch:Engy_Chg(Wh), E_dch_2:Engy_DChg(Wh)
    channel_2, cyc_2, step_2, raw_step_2, stat_2, U_i_2, U_e_2, I_i_2, I_e_2, C_2_2, endure_t_2, rel_t_2, abs_t_2, cap_dch_2, cap_ch_2, cap_dch_2_2, nE_2, E_ch, E_dch_2 = result_arr2.T
    
    ###############################################################################################################################
    ###############################################################################################################################
    
    #Creating one array with all Detail containing sheets
    # An empty array is needed to add all arrays with np.concatenate 
    result_arr3 = np.empty([0 ,11 ]) # we have 11 columns
    df_list={} #this is a dictionary
    
    # idx_sheet is the index of a sheet in the "Detail_cont_sheet_list"
    for idx_sheet in range(len(Detail_cont_sheet_list)):
        df_list[idx_sheet] = pd.read_excel(excel_file, sheet_name = Detail_cont_sheet_list[idx_sheet]).to_numpy()
        result_arr3 = np.concatenate([result_arr3, df_list[idx_sheet]])
    
    # adding the sheets of the second Workbook
    df_list_1={}
    for idx_sheet in range(len(Detail_cont_sheet_list_1)):
        df_list_1[idx_sheet] = pd.read_excel(excel_file_1, sheet_name = Detail_cont_sheet_list_1[idx_sheet]).to_numpy()
        result_arr3 = np.concatenate([result_arr3, df_list_1[idx_sheet]])
        
    # seperating columns, by making a table
    # rec_idx_3:record index, stat_3:status, jump_3:JumpTo, cyc_3:cycle, step_3, cur_3:current(mA), U_3:voltage(V), C_3:Capacity(mAh), E_3:Energy(Wh), rel_t_3: relative time, abs_t_3:absolute time
    rec_idx_3, stat_3, jump_3, cyc_3, step_3, cur_3, U_3, C_3, E_3, rel_t_3, abs_t_3 = result_arr3.T
    
    
    
    ###############################################################################################################################
    ###############################################################################################################################
    


    #    
    # creating an array without rest times (wrt)
    # first finding any rows with the input "Rest" and write index in new array arr3_rt_idx
    arr3_rt_idx = np.where(result_arr3 == "Rest")[0]
    
    
    
    arr3_wrt = np.delete(result_arr3, arr3_rt_idx, 0)
    rec_idx_3_wrt, stat_3_wrt, jump_3_wrt, cyc_3_wrt, step_3_wrt, cur_3_wrt, U_3_wrt, C_3_wrt, E_3_wrt, rel_t_3_wrt, 	abs_t_3_wrt = arr3_wrt.T
    #
    
    
    t_hours = (rec_idx_3_wrt - 1)/1200
    
    coul_eff_fct()

Ich habe eine Funktion für 2 Workbooks definiert, für 4, für 5 etc. Aber ich denke mir, das kann nicht die Lösung sein....Hat jmd Tips für mich?

:?:
Sirius3
User
Beiträge: 18218
Registriert: Sonntag 21. Oktober 2012, 17:20

Benutze kein `global`, sondern schreibe echte Funktionen, die alles, was sie brauchen, per Argumente bekommen, und die Ergebnisse per `return` zurückliefern.
Du solltest keinen kopierten Code in Deinen Funktionen haben. Schreibe eine Funktion, die eine Excel-Datei liest und rufe die in einer Schleife für alle Exceldatein auf.
Benutze keine Variablennamen, die kryptische Abkürzungen enthalten, oder durchnummeriert sind. Zweiteres sollte beim Befolgen der zweiten Anmerkung automatisch nicht mehr nötig sein.

Variablennamen sollten keine Datentypen im Namen haben, erst recht nicht, wenn sie falsch sind:

Code: Alles auswählen

df_list={} #this is a dictionary
Was Du tatsächlich mit den Daten machst, kann ich aus dem Code nicht erkennen. Vielleicht willst Du wirklich Pandas benutzen, statt so 20 einzelne Arrays zu benutzen.
Speedy
User
Beiträge: 11
Registriert: Mittwoch 4. September 2019, 11:29

Benutze kein `global`, sondern schreibe echte Funktionen, die alles, was sie brauchen, per Argumente bekommen, und die Ergebnisse per `return` zurückliefern.
Warum findest du die Nutzung von "global" problematisch?

Was Du tatsächlich mit den Daten machst, kann ich aus dem Code nicht erkennen. Vielleicht willst Du wirklich Pandas benutzen, statt so 20 einzelne Arrays zu benutzen.
Ja das stimmt, es ist unübersichtlich. Da ich mit numpy besser vertraut war, habe ich versucht, alles in numpy umzuformen...
Benutze kein `global`, sondern schreibe echte Funktionen, die alles, was sie brauchen, per Argumente bekommen, und die Ergebnisse per `return` zurückliefern.
Du solltest keinen kopierten Code in Deinen Funktionen haben. Schreibe eine Funktion, die eine Excel-Datei liest und rufe die in einer Schleife für alle Exceldatein auf.
Benutze keine Variablennamen, die kryptische Abkürzungen enthalten, oder durchnummeriert sind. Zweiteres sollte beim Befolgen der zweiten Anmerkung automatisch nicht mehr nötig sein.

Variablennamen sollten keine Datentypen im Namen haben, erst recht nicht, wenn sie falsch sind:

Alles klar! Ich werde mich die Tage daran setzen, und wenn ich einen ersten Entwurf habe, schreibe ich nochmal :)
Benutzeravatar
__blackjack__
User
Beiträge: 13925
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Speedy: Bei ``global`` muss man sich das ganze Programm anschauen wo der Name dann überall benutzt wird und wo der noch überall ``global`` ist, also auch neue Werte zugewiesen bekommen kann. Bei jedem Aufruf einer anderen Funktion kannst Du dann am Aufruf selbst nicht sehen was diese Funktion an globalen Variablen verwendet, oder gar ändert, ohne tatsächlich in diese Funktion hinein zu schauen. Wenn man Funktionen dagegen so benutzt wie sie gedacht sind, siehst Du was übergeben wird, und das ist dann alles was die Funktion benötigt, und was sie zurück gibt.

Funktionen sollten von der Idee her so etwas sie Kästen sein in die man nicht hinein schauen muss wenn man weiss was sie als Argumente bekommen und Rückgabewerte liefern, weil man dann, *wenn* man in eine Funktion hinein schaut, nur *dort* hineinschauen muss um sie zu verstehen, und nicht auch in dem Code von anderen Funktionen. Das macht Programme leichter verständlich, weil man sich immer auf einzelne Funktionen beschränken kann, ohne immer das gesamte Programm im Kopf zu haben.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
Antworten