Dies ist seit sehr sehr sehr langer Zeit das erste Mal, dass ich in einem neuen Forum einen ersten Post abgebe und ich bin gespannt wie die Python-Community hier so drauf ist

Außerdem ist es gleichermaßen spannend mal wieder auf der Seite der Fragesteller zu stehen, denn ich habe erst vor kurzem damit angefangen Pyhton zu lernen...
Kurze Vorstellung gefällig? Okay, ich bin 34, Handwerker mit IT-Hintergrund und begeisterter "Neue-Sachen-Lerner" - außerdem schreibe ich derzeit an meiner Masterarbeit im Bereich KI. In den letzten Wochen habe ich mich durch die kaggle.com-Micro-Kurse, sowie einige Online-Tutorials geschlagen um eine erste praktische Übersicht über die Möglichkeiten von Python, pandas und Co., speziell im Hinblick auf das "Verschneiden" von Daten zwecks arbeiten mit neuronalen Netzen zu bekommen und habe schon einige Eigenschaften der Sprache kennengelernt, die mir in anderen Sprachen bisher gefehlt haben. Aber genug dazu und bei Fragen, fragen^^
Nun aber zu meinem Anliegen:
Ich habe einen Datensatz, der folgendermaßen aussieht:
Code: Alles auswählen
bezirk;adrortsteil;ebekomplex;stiwo;wache;datuhr;datuhranleg;uhralarm;uhr3;uhr4;uhr7;uhr8;uhr1;uhr2
8;OHM;1;FEU1;08;2007-01-02 09:06:05;2007-01-02 09:07:03;2007-01-02 09:07:39;2007-01-02 09:08:16;NULL;NULL;NULL;NULL;2007-01-02 13:56:29
5;NIP;INTERN2;05;2007-01-02 09:11:58;2007-01-02 09:13:03;2007-01-02 09:14:41;2007-01-02 09:14:53;NULL;NULL;NULL;NULL;2007-01-02 09:39:41
Ich möchte nun fehlende Zeiten (NULL oder im DF NaT) durch spezielle mean-Values ersetzen.
Hierbei bin ich bisher wie folgt vorgegangen:
Ich habe Kombinationsgruppen gebildet, von denen ich die Differenz von Zeit A zu Zeit B berechne und am Ende über die jeweilige einen Durchschnitt für die jeweilige Gruppe bilde.
Das Ergebnis ist am Ende ein neuer DF, der zu jeder Kombination "stiwo", "jahr", "wache" die entsprechenden Durchschnittszeiten enthält. Nun möchte ich diese Durchschnittszeiten an jenen Stellen in den Rohdaten einfügen, bei denen Zeitfelder leer/null sind.
Könnt ihr mein Problem bitte lösen, denn ich kann eigentlich gar kein Python und bin auch zu faul

Folgendes habe ich bisher (wahrscheinlicch viel zu umständlich) gebbaut:
Code: Alles auswählen
import pandas as pd
data_file = 'archiv.1k.csv'
data_file = 'archiv.2.csv'
#data_file = 'archiv.10k.csv'
#data_file = 'archiv.100k.csv'
#data_file = 'archiv.csv'
###########################################
# Daten einlesen
###########################################
date_columns = ['datuhr', 'datuhranleg', 'uhralarm', 'uhr3', 'uhr4', 'uhr7', 'uhr8', 'uhr1', 'uhr2']
raw_data = pd.read_csv(data_file, delimiter=';', index_col='id', parse_dates=date_columns)
#raw_data.drop(columns=['plqr', 'plqh'], inplace=True)
drop_columns = ['bezirk', 'adrortsteil', 'ebekomplex', 'datuhr', 'datuhranleg', 'uhralarm', 'uhr3', 'uhr4', 'uhr7', 'uhr8', 'uhr1', 'uhr2']
def get_mean_times(data, combinations, agg_groups, agg_func):
"""
Splittet data anhand cominations in neue DataFrames mit den in combinations enthaltenen
Feldern. Filtert NaT/null-Values und berechnet die Differenz von comb in cominations zwischen
comb[0] und comb[1]. Anschließend werden die Datensätze nach stiwo, jahr und wache gruppiert
und für jede Kombination der Mittelwert berechnet.
Dieser Gruppen-Mittelwert wird dazu verwendet fehlende Datensätze aufzufüllen.
"""
result = pd.DataFrame()
for comb in combinations:
dc = set(drop_columns) - set(comb)
dv = data.loc[data[comb[0]].notnull() & data[comb[1]].notnull()].drop(columns=dc)
diffcol = comb[0] + '_' + comb[1]
dv['jahr'] = dv[comb[0]].dt.year
dv[diffcol] = dv[comb[1]].sub(dv[comb[0]], axis=0).astype('timedelta64[s]')
dv.drop(columns=comb, inplace=True)
group = dv.groupby(agg_groups).mean().reset_index()
if result.size == 0:
result = group
else:
result = pd.merge(result, group, on=['stiwo', 'jahr', 'wache'])
return result
combinations = [
['datuhr', 'uhralarm'], #Zuteilung der Einsatznummer - Alarmierung
['uhralarm', 'uhr3'], #Alarmierung bis Auftrag übernommen
['uhr3', 'uhr4'], #Auftrag übernomen bis E-Stelle an
['uhr4', 'uhr7'], #E-Stelle an bis Patient aufgenommen
['uhr7', 'uhr8'], #Patient augenommen bis Krankenhaus an
['uhr8', 'uhr1'], #Krankenhaus an bis Einsatzbereit über Funk
['uhr1', 'uhr2'], #Einsatzbereit über Funk bis Einsatzbereit auf Wache
['uhralarm', 'uhr1'] #Alarmiert bis Einsatzbereit
]
agg_groups = ['stiwo', 'jahr', 'wache']
agg_func = ['mean']
mean_times = get_mean_times(raw_data, combinations, agg_groups, agg_func)
Dabei steht am Ende in mean_times folgender Inhalt:
Code: Alles auswählen
stiwo jahr wache datuhr_uhralarm uhralarm_uhr3 uhr3_uhr4 uhr4_uhr7 uhr7_uhr8 uhr8_uhr1 uhr1_uhr2 uhralarm_uhr1
1 INTERN1 2007 2 175.75 28.75 11.0 8.0 12.0 8.0 7.0 135.0
2 INTERN2 2007 4 118.00 10.00 5.0 100.0 8.0 5.0 6.0 128.0
3 INTERN2 2007 5 537.25 37.50 11.5 22.0 27.0 7.0 12.0 81.5
Die Grundidee war, ähnlich wie mit anderen Sprachen und/oder SQL durch die Datensätze zu iterieren und für jeden Datensatz zu prüfen ob eine Zeit fehlt und wenn ja welche und diese dann aus den mean_times abzufragen. Beispiel:
Code: Alles auswählen
8;OHM;1;FEU1;08;2007-01-02 09:06:05;2007-01-02 09:07:03;2007-01-02 09:07:39;2007-01-02 09:08:16;NULL;NULL;NULL;NULL;2007-01-02 13:56:29
Code: Alles auswählen
mean_for_current = mean_times.loc[(mean_times.stiwo == 'FEU1') & (mean_times.jahr==2007) & (mean_times.wache == 8)]
0 FEU1 2007 8 104.00 93.00 8.0 17240.0 4.0 7.0 8.0 17352.0 #Beispiel
Nun müsste der Wert uhr3_uhr4 (was dem Timedelta entspricht) auf den Wert in uhr3 addiert und in uhr4 geschrieben werden, usw...
Hier fehlt mir nun leider gänzlich eine sinnvolle Idee. Was wären geeignete Methoden von pandas um soetwas zu tun?
Ist meine grundsätzliche Vorgehensweise okay oder zu stark Java & Co. belastet? Wenn ja, wie macht man es besser?
Danke für eure Anregungen!
nutelli