2017-05-31 3 views
0

Ich habe ein Datenframe mit 2 Spalten ['Startdt'] und ['Enddt']. Sie sind Datetime-Objekte in einem PANDA-Datenrahmen. Ich möchte eine neue Spalte erstellen, die nach jeder Kombination von 'startdt' und 'enddt' gruppiert ist und mit Werten in den Zeilen der Spalte gefüllt wird, mit 10-Minuten-Inkrementwerten von 'startdt' bis zu/include 'enddt'-Spalten.PANDAs: Erstellen 'gefüllt' Spalte mit inkrementellen Datetime-Werte, zwischen 2 Datumsangaben (Bereich) Spalten

Hier ist ein Beispiel für 2 GROUPINGS von 'startdt' und 'enddt'; Beachten Sie, dass die letzte Zeile in der Gruppierung fast immer weniger als 10 Minuten beträgt, da sie den Wert von "enddt" enthalten und an diesen gebunden sein muss, um den gesamten Bereich zwischen "startdt" und "enddt" zu erfassen.

startdt    endt    newcol 
2017-05-27 11:30:00 2017-05-27 11:55:00 2017-05-27 11:40:00 
2017-05-27 11:30:00 2017-05-27 11:55:00 2017-05-27 11:50:00 
2017-05-27 11:30:00 2017-05-27 11:55:00 2017-05-27 11:55:00 
2017-05-27 14:54:00 2017-05-27 15:33:00 2017-05-27 15:04:00 
2017-05-27 14:54:00 2017-05-27 15:33:00 2017-05-27 15:14:00 
2017-05-27 14:54:00 2017-05-27 15:33:00 2017-05-27 15:24:00 
2017-05-27 14:54:00 2017-05-27 15:33:00 2017-05-27 15:33:00 

‚Newcol‘ werden erstellen doppelte Zeilen der anderen 2 Spalten im df offensichtlich wird aber eindeutig sein Zeilen mit 10 (oder weniger in letzten Reihe der Gruppe) Minuten-Schritten zwischen diesen ‚STARTDT‘ und ' enddt‘Spalten

+0

Ich möchte Sie ausdrücklich den Wert in newcol in Frage gesetzt schreiben. Ich verstehe nicht die Spalte von 10-Minuten-Schritten zwischen den Spalten "startdt" und "enddt". Great –

Antwort

1

definieren eine benutzerdefinierte (generic) Transformationsfunktion

def transform_func(row, freq, include_last): 
    start = row['startdt'].min() 
    end = row['endt'].max() 
    idx = pd.DatetimeIndex(start=start, end=end, freq=freq) 
    if include_last and idx[-1] != end: 
     idx = idx.append(pd.DatetimeIndex([end])) 
    return pd.DataFrame(data={'newcol': idx}) 

Dies nimmt die start und end und macht eine DatetimeIndex darauf basiert. Sie können die Häufigkeit angeben und ob das Intervall sollte

eine spezifische Funktion

Sie können diese Transformation erstellen geschlossen werden tun, indem sie entweder so dass die ursprüngliche transfrom_func weniger generisch und vielseitig, functools.partial oder lambda. Ich wähle das Lambda

transform_func10 = lambda x: transform_func(x, freq='10Min', include_last=True) 

tun, um die Aggregation

Aggregate mit dieser speziellen Funktion

d = df.groupby(['startdt', 'endt']).agg(transform_func10) 

Ergebnis

            newcol 
startdt     endt   
2017-05-27 11:30:00  2017-05-27 11:55:00 0  2017-05-27 11:30:00 
               1  2017-05-27 11:40:00 
               2  2017-05-27 11:50:00 
               3  2017-05-27 11:55:00 
2017-05-27 14:54:00  2017-05-27 15:33:00 0  2017-05-27 14:54:00 
               1  2017-05-27 15:04:00 
               2  2017-05-27 15:14:00 
               3  2017-05-27 15:24:00 
               4  2017-05-27 15:33:00 

Reformiert

d.reset_index().drop('level_2', axis=1).rename(columns={0: 'newcol'}) ergibt:

startdt     endt     newcol 
0 2017-05-27 11:30:00  2017-05-27 11:55:00  2017-05-27 11:30:00 
1 2017-05-27 11:30:00  2017-05-27 11:55:00  2017-05-27 11:40:00 
2 2017-05-27 11:30:00  2017-05-27 11:55:00  2017-05-27 11:50:00 
3 2017-05-27 11:30:00  2017-05-27 11:55:00  2017-05-27 11:55:00 
4 2017-05-27 14:54:00  2017-05-27 15:33:00  2017-05-27 14:54:00 
5 2017-05-27 14:54:00  2017-05-27 15:33:00  2017-05-27 15:04:00 
6 2017-05-27 14:54:00  2017-05-27 15:33:00  2017-05-27 15:14:00 
7 2017-05-27 14:54:00  2017-05-27 15:33:00  2017-05-27 15:24:00 
8 2017-05-27 14:54:00  2017-05-27 15:33:00  2017-05-27 15:33:00 
+0

Große Antwort, das funktioniert sehr knapp. – PR102012

Verwandte Themen