Group by

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Bl3nder
User
Beiträge: 139
Registriert: Freitag 3. Januar 2020, 17:07

Hey Leute Ich benötige eure hilfe ( Ich habe so eine Frage in der Vergangenheit schon mal gestellt und habe mich auch versucht mit der Dokumentation auseinander zu setzten ) jedoch komme Ich leider einfach nicht weiter .




Code: Alles auswählen

from pathlib import Path
import pandas as pd
import shutil
import time

#Einstellungen für Pandas:
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', None)
pd.set_option('display.max_colwidth', -1)
pd.set_option('mode.chained_assignment', None)  # Schaltet SettingWithCopyWarning aus






# Pfade:
Dummy_ordner = Path(r"C:\Users\Marcel\Desktop\Dieter_Klimareport\Dieter_Auswertung")

ORDNER_MIT_DATEN = Path(r"C:\Users\Marcel\Desktop\Dieter_Klimareport\Dieter_Auswertung\Fertigdaten_2020_02.wrt")

Pfad_Excel = Path(r"C:\Users\Marcel\Desktop\Dieter_Klimareport\Unterlagen_Manfred\Muster Klimazettel MAT - Kopie.xlsx")



# Kanal-Nummern: # Excel-Nummer +1 da Datum später weggenommen wird
KEIN_KANAL = 0
LUFTTEMPERATUR = 2
RELATIVE_LUFTFEUCHTIGKEIT = 289
MAX_TEMPERATUR = 249
MIN_TEMPERATUR = 248
NIEDERSCHLAG = 261
SONNENSCHEINDAUER = 18
MAX_WIND = 139
WINDRICHTUNG = 73

#Intervalle
TAG = "D"
Uhrzeit_1 = "06:00:00"
Uhrzeit_2 = "6:50:00"
Uhrzeit_3 = "13:50:00"
Uhrzeit_4 = "20:50:00"
Uhrzeit_5 = "23:59:00"

#Umrechnungsfaktoren
STUNDE_IN_SEKUNDEN = 60*60


#----------------------------------------Programm Anfang----------------------------------------------------------------



def musterdatei_neu_erzeugen(pfad):

    if not pfad.exists():
        shutil.copy(r"C:\Users\Marcel\Desktop\Dieter_Klimareport\Unterlagen_Manfred\Muster Klimazettel MAT.xlsx",
                    r"C:\Users\Marcel\Desktop\Dieter_Klimareport\Unterlagen_Manfred\Muster Klimazettel MAT - Kopie.xlsx")



def daten_einlesen(daten):

    """Hier werden die Daten eingelesen und zurückgegeben"""

    "Anmerkung low_memory ist standardmäig auf True dadurch läuft zwar das Programm schneller und benutzt weniger" \
    "Arbeitsspeicher jedoch werden dadurch gemische Colums ( vom Typ her erzeugt da diese nicht so schenll zugeordnet" \
    "werden können um das zu beheneben habe Ich es auf False gesetzt"

    df = pd.read_csv(daten,sep = "|",header = None,parse_dates = True,low_memory = False) #low_Memory = False da pandas nicht alle typen bestimmen kann
    df = df.replace("******", "NaN")
    df.dropna(how = "all",inplace = True)
    df = df.fillna("")
    df[0] = pd.to_datetime(df[0])
    df = df.set_index(0)  # df = zuordnen dann bleibt 1 spalte erhalten
    anfang_index = df.index.tolist()[0]  # ermittelt den ersten Index eintrag
    ende_index = df.index.tolist()[-1]  # ermittelt den letzten Index eintrag

    return df,anfang_index,ende_index
def windgeschwindigkeit_mit_windrichtung(datensatz,kanalnummer_max_wind,kanalnummer_windrichtung,intervall):
    """Es wird ein neuer Datenframe erstellt mit der Windrichtung und dem Max Wind (nummer 73,139),in einem neuen Datenframe
    werden die beiden Spalten in Abnhänihkeit der rechten Spalte (1 = 139) mit der freq D gropiert | der Index und die Spalte 0
    werden Tageweise ausgewählt abhängig davon wo der Max Wert der Rechten Spalte war"""

    df = datensatz.loc[:,[kanalnummer_windrichtung,kanalnummer_max_wind]]
    df_neu= df.loc[df.groupby(pd.Grouper(freq = intervall)).idxmax().iloc[:, 1]]
    return df_neu
def daten_mit_zeit_index(datensatz,kanalnummer,intervall):
    """Wir extrahieren die Spalte kanalnummer_lufttemperatur aus dem Datenframe datensatz danach suchen
    wir im Index an Einträgen mit der Zeit intervalle in dem Fall übergeben wir diese zum Beispiel 06:50:00 und erhalten
    in Integerwerte zurück in welcher Reihe sich die Zeit befindet wodruch wir gleichzeitig mit dem Integerwert auf den
    Messwert zurgreifen können da es sich hier um 1 Dimensonale Werte handeln werden Series zurückgegeben"""



    series= datensatz.loc[:,kanalnummer]
    index = series.index.indexer_at_time(time = intervall)
    series_mit_neuem_index = pd.Series(series.iloc[index],dtype = float)
    return series_mit_neuem_index


def series_zu_Datenframe(Werte1,Werte2,Werte3,Name1,Name2,Name3):
    """"Die übergebenen Werte ( Series) werden von ihrem Index getrennt damit Sie einen einheitlichen erhalten( 1....)
        danach werden Sie zusammengefasst zu einem Dataframe ,wird aktuell nicht benötigt da die Rechnung
        des Mittelwertes in Excel stattfindet"""

    Zeitraum1 = pd.Series(Werte1.reset_index(drop = True),name = Name1)
    Zeitraum2 = pd.Series(Werte2.reset_index(drop = True),name = Name2)
    Zeitraum3 = pd.Series(Werte3.reset_index(drop = True),name = Name3)
    Zeitraum4 = pd.Series(Werte3.reset_index(drop = True),name = "lufttemp_20_50")
    df = pd.concat([Zeitraum1,Zeitraum2,Zeitraum3,Zeitraum4],axis = 1)#axis 1 damit Sie nebeneinanderer gereiht werden ( 1 = Colum 0 = Index)
    return df



def sonnenscheindauer_in_std(datensatz,kanalnummer,Umrechnungsfaktor):
    """Aus dem Datensatz wird die Spalte mit den Sonnenwerten extrahiert diese sind jedoch in Sekunden daher wird die
    Tagessumme ermittelt und diese durch den Umrechnungswert dividiert um die Tagessumme in Stunden zu erhalten danch
    werden die Werte auf 2 Nachkommastellen gerunden damit diese nicht zu lang werden"""

    series = datensatz.loc[:,kanalnummer]
    series_summe_pro_tag = series.groupby(pd.Grouper(freq = "D")).sum()
    sonnenstunden = series_summe_pro_tag.div(Umrechnungsfaktor)#.round(decimals = 2)
    return sonnenstunden



def daten_zusammenfassen(windrichtung_abhaengigkeit_windgeschwindigkeit,lufttemp_06_50,lufttemp_13_50,lufttemp_20_50,tml,relativ_luftfeucht_06_50,relativ_luftfeucht_13_50,relativ_luftfeucht_20_50,tmf,max_temp,min_temp,sonnenschein,niederschlag):
    """HINWEIS AKTUELL WERDEN tml und tmf NICHT benutzt da diese in Excel zusammen gefasst werden
       Die Daten werden in mehreren Datenframes zusammengefasst damit diese nachher einzeln in die Excel Datei
       geschrieben werden können ( es befinden sich dort Spalten mit Formeln -> ein großer Datenframe würde da nur stören"""

    wert1 = windrichtung_abhaengigkeit_windgeschwindigkeit.reset_index(drop = True)
    wert2 = lufttemp_06_50.reset_index(drop = True)
    wert3 = lufttemp_13_50.reset_index(drop = True)
    wert4 = lufttemp_20_50.reset_index(drop = True)
    #wert5 = tml.reset_index(drop = True)
    wert6 = relativ_luftfeucht_06_50.reset_index(drop = True)
    wert7 = relativ_luftfeucht_13_50.reset_index(drop = True)
    wert8 = relativ_luftfeucht_20_50.reset_index(drop = True)
    #wert9 = tmf.reset_index(drop = True)
    wert10 = max_temp.reset_index(drop = True)
    wert11 = min_temp.reset_index(drop = True)
    wert12 = sonnenschein.reset_index(drop = True)
    wert13 = niederschlag.reset_index(drop = True)


    df1 = pd.concat([wert1,wert2,wert3,wert4],axis = 1)
    df2 = pd.concat([wert6,wert7,wert8],axis = 1)
    df3 = pd.concat([wert10,wert11,wert12,wert13],axis = 1)

    return df1,df2,df3

def daten_in_excel_schreiben(datenframe1,datenframe2,datenframe3,pfad):

        df1 = datenframe1.iloc[:10]
        df1_1 = datenframe1.iloc[10:20]
        df1_2 = datenframe1.iloc[20:]
        df2 = datenframe2.iloc[:10]
        df2_1 = datenframe2.iloc[10:20]
        df2_2 = datenframe2.iloc[20:]
        df3 = datenframe3.iloc[:10]
        df3_1 = datenframe3.iloc[10:20]
        df3_2 = datenframe3.iloc[20:]




        with pd.ExcelWriter(pfad, engine="openpyxl", mode="a") as writer:
            writer.sheets = {sheet.title: sheet for sheet in writer.book}  # sorgt dafür das kein neues Arbeitsblatt erschaffen wird
            df1.to_excel(writer, sheet_name = "Klimareport_MAT", header = None, index = None,startrow = 8, startcol = 1)
            df1_1.to_excel(writer, sheet_name = "Klimareport_MAT", header = None, index = None, startrow = 19, startcol = 1)
            df1_2.to_excel(writer, sheet_name = "Klimareport_MAT", header = None, index = None, startrow = 30, startcol = 1)
            df2.to_excel(writer, sheet_name = "Klimareport_MAT", header = None, index = None, startrow = 8, startcol = 7)
            df2_1.to_excel(writer, sheet_name = "Klimareport_MAT", header = None, index = None, startrow = 19, startcol = 7)
            df2_2.to_excel(writer, sheet_name = "Klimareport_MAT", header = None, index = None, startrow = 30, startcol = 7)
            df3.to_excel(writer, sheet_name = "Klimareport_MAT", header = None, index = None, startrow = 8, startcol = 11)
            df3_1.to_excel(writer, sheet_name = "Klimareport_MAT", header = None, index = None, startrow = 19, startcol = 11)
            df3_2.to_excel(writer, sheet_name = "Klimareport_MAT", header = None, index = None, startrow = 30, startcol = 11)







def main():
    start_time = time.time()
    musterdatei_neu_erzeugen(Pfad_Excel)
    ausgelsene_daten,anfangs_index,ende_index = daten_einlesen(ORDNER_MIT_DATEN)#Dataframe
    windrichtung_abhaengigkeit_windgeschwindigkeit = windgeschwindigkeit_mit_windrichtung(ausgelsene_daten,MAX_WIND,WINDRICHTUNG,TAG)#Dataframe,=> nachher in Excel
    lufttemp_06_50 = daten_mit_zeit_index(ausgelsene_daten, LUFTTEMPERATUR, Uhrzeit_2)#Series
    lufttemp_13_50 = daten_mit_zeit_index(ausgelsene_daten,LUFTTEMPERATUR,Uhrzeit_3)#Series
    lufttemp_20_50 = daten_mit_zeit_index(ausgelsene_daten,LUFTTEMPERATUR,Uhrzeit_4)#Series
    tml = series_zu_Datenframe(lufttemp_06_50,lufttemp_13_50,lufttemp_20_50,"lufttemp_06_50","lufttemp_13_50", "lufttemp_20_50")#Dataframe => nachher in Excel
    relativ_luftfeucht_06_50 = daten_mit_zeit_index(ausgelsene_daten, RELATIVE_LUFTFEUCHTIGKEIT, Uhrzeit_2)
    relativ_luftfeucht_13_50 = daten_mit_zeit_index(ausgelsene_daten,RELATIVE_LUFTFEUCHTIGKEIT,Uhrzeit_3)
    relativ_luftfeucht_20_50 = daten_mit_zeit_index(ausgelsene_daten,RELATIVE_LUFTFEUCHTIGKEIT,Uhrzeit_4)
    tmf = series_zu_Datenframe(relativ_luftfeucht_06_50,relativ_luftfeucht_13_50,relativ_luftfeucht_20_50," relativ_luftfeucht_06_50"," relativ_luftfeucht_13_50","relativ_luftfeucht_20_50")#Dataframe => nachher in Excel
    max_temp = daten_mit_zeit_index(ausgelsene_daten,MAX_TEMPERATUR,Uhrzeit_1)#Series ->nachher in Excel
    min_temp = daten_mit_zeit_index(ausgelsene_daten,MIN_TEMPERATUR,Uhrzeit_1)#Series ->nachher in Excel
    sonnenschein = sonnenscheindauer_in_std(ausgelsene_daten,SONNENSCHEINDAUER,STUNDE_IN_SEKUNDEN)#Series ->nachher in Excel
    niederschlag = daten_mit_zeit_index(ausgelsene_daten,NIEDERSCHLAG,Uhrzeit_5)#Series ->nachher in Excel
    datenframe1,datenframe2,datenframe3=daten_zusammenfassen(windrichtung_abhaengigkeit_windgeschwindigkeit,lufttemp_06_50,lufttemp_13_50,lufttemp_20_50,tml,relativ_luftfeucht_06_50,relativ_luftfeucht_13_50,relativ_luftfeucht_20_50,tmf,max_temp,min_temp,sonnenschein,niederschlag)
    daten_in_excel_schreiben(datenframe1,datenframe2,datenframe3,Pfad_Excel)
    print("Benötigte Zeit", time.time() - start_time)


if __name__=="__main__":
    main()

Folgendes Problem:


Ich habe ein Datensatz 2020_02 den lade Ich rein ( der durchläuft das Skript und macht genau was er soll ) als Ich nun das "Programm " fertig gestellt habe habe Ich es mit einem anderen Datensatz Versucht und es sind Fehler aufgetreten.

Es geht um die Funktionwindgeschwindigkeit_mit_windrichtung:

Was diese eigentlich genau machen soll ist folgendes Ich nehme zwei bestimmte Spalten wo bei der Index ein Daum mit Uhrzeit ist ( jede Minute) :

Code: Alles auswählen

                      73   139
0                             
2020-02-01 17:56:00  246  17.9
2020-02-02 01:04:00  246  15.8
2020-02-03 16:12:00  270  14.2
2020-02-04 06:58:00  245  11.6
2020-02-05 16:20:00  277  8.5 
2020-02-06 03:25:00  241  7.7 
2020-02-07 09:53:00  134  10.3
2020-02-08 16:35:00  205  11.1
2020-02-09 17:40:00  201  25.8
2020-02-10 08:29:00  255  24.1
2020-02-11 13:40:00  249  21.5
2020-02-12 11:02:00  253  18.6
2020-02-13 12:55:00  142  15.1
2020-02-14 21:00:00  179  9.0 
2020-02-15 22:43:00  191  18.6
2020-02-16 16:54:00  199  25.5
2020-02-17 03:56:00  239  18.8
2020-02-18 09:37:00  238  15.6
2020-02-19 10:58:00  254  15.8
2020-02-20 19:31:00  256  18.3
2020-02-21 22:10:00  208  16.3
2020-02-22 18:09:00  253  22.9
2020-02-23 13:16:00  248  25.3
2020-02-24 23:30:00  237  16.3
2020-02-25 12:38:00  244  18.7
2020-02-26 13:18:00  281  12.2
2020-02-27 02:57:00  233  9.0 
2020-02-28 18:42:00  181  16.6
2020-02-29 15:27:00  208  20.8
Ich ermittel hier den Max Wert von Kanal 139 und in abhängigkeit davon um welcher Uhrzeit das gewesen ist und welche Windrichtung wie hatten ( Kanal 73)


Ich habe dafür die Zeile aus dem Internet das Ich es leider nicht hinbekommen habe :

Code: Alles auswählen

df.loc[df.groupby(pd.Grouper(freq = intervall)).idxmax().iloc[:, 1]]
Ich bekomme zwar das Groupen und den Intervall hin aber wenn Ich dann mit max arbeite sind immer beide Spalten auf Max und nicht in abhängigkeit.

Wenn Ich nun ein andere Datei durchlaufen lasse bekomme Ich folgenden Fehler :

Wenn Ich die andere Datei bis vor die Stelle laufen lasse sieht alles gut aus :

Code: Alles auswählen

2018-07-29 18:06:00     158     3.0
2018-07-29 18:07:00     155     2.3
2018-07-29 18:08:00     153     2.8
2018-07-29 18:09:00     152     2.5
2018-07-29 18:10:00     154     2.8
2018-07-29 18:11:00     156     2.8
2018-07-29 18:12:00     152     2.4
2018-07-29 18:13:00     153     2.3
2018-07-29 18:14:00     152     2.8
2018-07-29 18:15:00     148     2.8
2018-07-29 18:16:00     149     2.2
2018-07-29 18:17:00     144     2.5
2018-07-29 18:18:00     150     2.0
2018-07-29 18:19:00     141     2.4
2018-07-29 18:20:00     140     2.2
2018-07-29 18:21:00     135     1.9
2018-07-29 18:22:00     135     2.2
2018-07-29 18:23:00     134     2.2
2018-07-29 18:24:00     133     2.4
2018-07-29 18:25:00     135     2.2
2018-07-29 18:26:00     133     2.1
2018-07-29 18:27:00     134     2.3
2018-07-29 18:28:00     134     2.9
2018-07-29 18:29:00     138     2.3
2018-07-29 18:30:00     136     2.3
2018-07-29 18:31:00     139     2.2
2018-07-29 18:32:00     135     2.7
2018-07-29 18:33:00     136     2.4
2018-07-29 18:34:00     138     2.4
2018-07-29 18:35:00     140     2.3
2018-07-29 18:36:00     142     2.5
2018-07-29 18:37:00     142     2.5
2018-07-29 18:38:00     140     2.4
2018-07-29 18:39:00     140     2.0
2018-07-29 18:40:00     138     2.3
2018-07-29 18:41:00     140     2.1
2018-07-29 18:42:00     139     2.0
2018-07-29 18:43:00     136     1.6
2018-07-29 18:44:00     130     1.7
2018-07-29 18:45:00     131     2.0
2018-07-29 18:46:00     127     2.0
2018-07-29 18:47:00     127     2.0
...
IndexError: single positional indexer is out-of-bounds


Ich habe natürlich versucht den Bezug von iloc etc zu ändern das führt nur zu anderen Fehlern irgendwas mit mask oder key error oder multidemensionalen ....


Ich hoffe ihr könnt mir helfen oder den einzeiler aufdröseln das Ich Ihn verstehe Ich bin leider am Ende mit meinen Ideen.



P.s Der Urdatensatz ist 40260 Zeilen in Excel groß deswegen kann ich den hier nicht zeigen wenn Ihn aber trotzdem sehen wollt kann Ich diesen hochladen
Eine Vision ohne Aktion bleibe eine Illusion
Bl3nder
User
Beiträge: 139
Registriert: Freitag 3. Januar 2020, 17:07

gelöscht
Eine Vision ohne Aktion bleibe eine Illusion
Sirius3
User
Beiträge: 18220
Registriert: Sonntag 21. Oktober 2012, 17:20

Konstanten schreibt man komplett groß, Variablen dagegen komplett klein. Statt Variablen durchzunummerieren sollte man ihnen sprechende Namen geben. Der absolute Pfad zu Dieter_Klimareport sollte nur einmal im Code vorkommen, alle anderen Pfade relativ zu diesem definiert werden.
Und zum Problem: read_csv hat das Argument na_values mit dem man die ***** gleich beim Einlesen richtig konvertieren kann.
Bl3nder
User
Beiträge: 139
Registriert: Freitag 3. Januar 2020, 17:07

@ Sirius danke für deine schnelle Hile

Die Konstanten habe Ich doch ausserhalb groß geschrieben oder soll man das auch in der Funktion machen ?

Also Ich habe gesehen das dadurch nun die Spalten nun kein object mehr sind sondern wieder float ( was Sie eigentlich auch sein sollten ) jedoch habe Ich immer noch den Index Fehler
Eine Vision ohne Aktion bleibe eine Illusion
Bl3nder
User
Beiträge: 139
Registriert: Freitag 3. Januar 2020, 17:07

Ich habe mal gesagt er soll df = df.fillna(-1) danach kommt eine neue Fehlermeldung:

KeyError: "None of [DatetimeIndex(['2018-07-01 09:10:00', '2018-07-02 13:23:00',\n '2018-07-03 16:57:00', '2018-07-04 16:58:00',\n '2018-07-05 11:47:00', '2018-07-06 12:09:00',\n '2018-07-07 15:11:00', '2018-07-08 12:40:00',\n '2018-07-09 11:49:00', '2018-07-10 15:24:00',\n '2018-07-11 16:50:00', '2018-07-12 13:22:00',\n '2018-07-13 13:48:00', '2018-07-14 15:41:00',\n '2018-07-15 12:54:00', '2018-07-16 10:13:00',\n '2018-07-17 15:53:00', '2018-07-18 09:06:00',\n '2018-07-19 18:10:00', '2018-07-20 18:14:00',\n '2018-07-21 14:37:00', '2018-07-22 10:42:00',\n '2018-07-23 09:38:00', '2018-07-24 18:38:00',\n '2018-07-25 15:39:00', '2018-07-26 12:46:00',\n '2018-07-27 12:30:00', '2018-07-28 15:02:00',\n '2018-07-29 13:22:00', '2018-07-30 11:32:00',\n '2018-07-31 12:49:00'],\n dtype='datetime64[ns]', freq=None)] are in the [columns]"
Eine Vision ohne Aktion bleibe eine Illusion
Bl3nder
User
Beiträge: 139
Registriert: Freitag 3. Januar 2020, 17:07

gelöscht
Eine Vision ohne Aktion bleibe eine Illusion
Bl3nder
User
Beiträge: 139
Registriert: Freitag 3. Januar 2020, 17:07

OK es funktioniert nun alles Ich habe beim ausprobieren df[df.groupby(pd.Grouper(freq = intervall)).idxmax().iloc[:, 1]] das loc vergessen Ich danke dir Sirius
Eine Vision ohne Aktion bleibe eine Illusion
Antworten