Laufzeitoptimierung_DataFrame: Spalte durchsuchen (Uhrzeit) -> If Bed. -> Neue Spalte erstellen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
NinoBaumann
User
Beiträge: 80
Registriert: Samstag 25. April 2020, 19:03

Hallo,

ich bin dabei den Ausschuss einer Industrieanlage auszuwerten. Die Rohdaten erhalte ich über eine csv Datei. Diese wandle ich in ein DataFrame um. In den Daten findet man die Teile Nr., Datum, Uhrzeit und dann eine ganze Reihe an versch. Ausschussgründen. Ich möchte das so auswerten, dass ich zum Schluss nach Datum, Teilenummer und Schicht (Frühschicht (FS), Spätschicht (SS), Nachtschicht (NS)) sortieren kann. Ich habe auch einen funktionierenden Code, welcher mir alles korrekt macht. Ich habe im Nachgang jedoch eine Zeitanalyse gemacht um herauszufinden, welcher Codeabschnitt am meisten Zeit benötigt. Das Ergebnis ist die for Schleife. Um zu erklären, was ich hier mache, noch folgende Info zu den Schichten. Schauen wir uns dazu mal den Schicht-Zyklus an:
Bsp für einen Arbeitstag:
03.03.2022_6 Uhr bis 14 Uhr = FS (vom 03.03.2023)_14 Uhr bis 22 Uhr = SS (vom 03.03.2023)_22 Uhr bis (6 Uhr am 04.03.2023)= NS (vom 03.03.2023)
Das heißt die Nachtschicht (NS) "geht über zwei Tage". Damit ich jetzt später beim Gruppieren (den Code habe ich jetzt hier nicht drinnen weil der schnell abgearbeitet ist) die Werte richtig zusammenfassen kann, also bswp. den Wert vom 03.03.2023 um 22.25 Uhr mit dem Wert vom 04.03.2023 und 2.25 Uhr (beides in der gleichen Nachtschicht. Also die Nachtschicht vom 03.03.2023), weise ich jeder Uhrzeit eine Schicht (FS,SS,NS) zu und speichere das in einer Liste (Schicht). Gleichzeitig schreibe ich in eine weitere leere liste (Datum1) das Datum aus der Zeile. Außer für die Zeitspanne der NS die im darauffolgenden Tag ist. Also von 0 Uhr bis 6 Uhr. Hier rechne ich einfach, einen Tag zurück. Also hat die Zeile z.B. den Wert 04.03.2023 um 4 Uhr, speichere ich als Datum den 03.03.2023 in der Datum1 Liste ab. Danach hänge ich beide Listen wieder an das DataFrame und kann im Nachgang richtig gruppieren. Es funktioniert auch wie gesagt alles, nur benötigt es relativ viel Zeit. Es gibt sicherlich eine viel smartere Lösung dafür. Kann mir hier jemand weiterhelfen?
Ich würde euch gerne ein Bild der Rohdaten noch zeigen. Aber, dumm wie ich bin, checke ich das hier nicht...
Die Spalte ANGELEGT_AM ist die Datumsangabe in den Rohdaten welche beispielhaft wie folgt abgespeichert ist: 14.09.2022 14:30:30

Code: Alles auswählen

dfData = pd.read_csv('')

dfData[['Datum','Uhrzeit']]=dfData.ANGELEGT_AM.str.split(expand=True)
dfData['Datum']= pd.to_datetime(dfData['Datum'],format= '%d.%m.%Y')
dfData['Uhrzeit'] = pd.to_datetime(dfData['Uhrzeit'],format= '%H:%M:%S' ).dt.time

Schicht=[]
Datum1=[]

for i in range(len(dfData)):
    
    if dfData.iloc[i]['Uhrzeit']>=datetime.strptime('06:00:00', '%H:%M:%S').time() and dfData.iloc[i]['Uhrzeit']<datetime.strptime('14:00:00', '%H:%M:%S').time():
        Schicht.append('FS')
        Datum1.append(dfData.iloc[i]['Datum'].date())
    if dfData.iloc[i]['Uhrzeit']>=datetime.strptime('14:00:00', '%H:%M:%S').time() and dfData.iloc[i]['Uhrzeit']<datetime.strptime('22:00:00', '%H:%M:%S').time():
        Schicht.append('SS')
        Datum1.append(dfData.iloc[i]['Datum'].date())
    if dfData.iloc[i]['Uhrzeit']>=datetime.strptime('22:00:00', '%H:%M:%S').time():
        Schicht.append('NS')
        Datum1.append(dfData.iloc[i]['Datum'].date())
    if dfData.iloc[i]['Uhrzeit']>=datetime.strptime('00:00:00', '%H:%M:%S').time() and dfData.iloc[i]['Uhrzeit']<datetime.strptime('06:00:00', '%H:%M:%S').time():
        Schicht.append('NS')
        Datum1.append((dfData.iloc[i]['Datum']-timedelta(1)).date())[/color]

dfData.insert(loc=0, column='Datum1', value=Datum1)
dfData.insert(loc=1, column='Schicht', value=Schicht)
Benutzeravatar
grubenfox
User
Beiträge: 612
Registriert: Freitag 2. Dezember 2022, 15:49

In unix_timestamp bzw. Sekunden umrechnen. Von Pandas habe ich keinen Plan, aber offenbar gibt es auch dort was:
https://www.geeksforgeeks.org/python-pa ... mp/?ref=rp

Dann beginnt die Frühschicht am Tag Y bei Sekunde X und geht bis Sekunde X+8*3600-1, die Spätschicht von X+8*3600 bis X+16*3600-1 und die Nachtschicht von X+16*3600 bis X+24*3600-1 (und bei X+24*3600 beginnt die Frühschicht des Tages Y+1) und man hat das Gefummel mit den Listen nicht mehr...

Hier noch für's übliche Python-DateTime:
https://www.geeksforgeeks.org/how-to-co ... in-python/

P.S.: "man hat das Gefummel mit den Listen hoffnungsweise nicht mehr..." jedenfalls entfällt die besondere Behandlung vom Datum bei der ganzen Geschichte
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

@grubenfox: Mit timestamps möchte man eigentlich nicht Arbeiten, was dsa noch zusätzlich schwierig macht, ist dass das ja ein Datumsformat ist, hier geht es aber nur um Zeiten.
@NinoBaumann: Wenn man in Pandas Schleifen über Indizes schreibt, dann macht man etwas falsch.
Datum und Uhrzeit gehören zusammen, die sollten nicht in zwei unterschiedlichen Spalten stehen.
Das Datumsfeld sollte schon beim Einlesen in Datetime umgewandelt werden, nicht hinterher.

Code: Alles auswählen

URL = ''
dfData = pd.read_csv(URL, parse_dates=["ANGELEGT_AM"], day_first=True)

times = dfData['ANGELEGT_AM'].dt.time
dfData['Schicht'] = ""
dfData['Schicht'][(times >= datetime.time(6, 0)) & (times < datetime.time(14, 0))] = 'FS'
dfData['Schicht'][(times >= datetime.time(14, 0)) & (times < datetime.time(22, 0))] = 'SS'
dfData['Schicht'][(times >= datetime.time(22, 0)) | (times < datetime.time(6, 0))] = 'NS'

dfData['DatumSchicht'] = dfData['ANGELEGT_AM'].dt.date
dfData['DatumSchicht'][times < datetime.time(6, 0)] -= datetime.timedelta(days=1)
NinoBaumann
User
Beiträge: 80
Registriert: Samstag 25. April 2020, 19:03

Hallo Sirius,

danke für die Hilfestellung. Hat alles funktioniert. Kurze Frage noch zur letzten Codezeile. Hier steht ja "-= datetime.timedelta(days=1)". Wieso steht da nicht nur Minus, sondern auch ein Gleichheitszeichen? Finde im Internet dazu leider nichts.

MfG
Nino
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Weil es Subtraktion der rechten Seite von der linken “in place” durchführt, also bei a -= b eigentlich a = a - b durchgeführt wird.
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@NinoBaumann: Bei Operatoren (und Namen aus der Standardbibliothek) kann man in der Python-Dokumentation in der Regel über den Index gehen. Dort bei „Symbols“ den ``-=``-Eintrag suchen und dort steht ein Link zur Referenzdokumentation über augmented assignment.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
NinoBaumann
User
Beiträge: 80
Registriert: Samstag 25. April 2020, 19:03

@__blackjack__ und __deets__
Danke für die weitere Hilfe!
Antworten