2016-11-09 3 views
5

Angenommen, ich habe zwei Datenrahmen:Pandas: Entfernen Sie alle Zeilen innerhalb des Zeitintervalls eines anderen Zeitindex der Serie (dh Zeitbereich Ausschluss)

#df1 
time 
2016-09-12 13:00:00.017 1.0 
2016-09-12 13:00:03.233 1.0 
2016-09-12 13:00:10.256 1.0 
2016-09-12 13:00:19.605 1.0 

#df2 
time 
2016-09-12 13:00:00.017 1.0 
2016-09-12 13:00:00.233 0.0 
2016-09-12 13:00:01.016 1.0 
2016-09-12 13:00:01.505 0.0 
2016-09-12 13:00:06.017 1.0 
2016-09-12 13:00:07.233 0.0 
2016-09-12 13:00:08.256 1.0 
2016-09-12 13:00:19.705 0.0 

ich alle Zeilen in df2 entfernen möchten, die bis zu 1 Sekunde sind der Zeitindizes in df1, so ergibt:

#result 
time 
2016-09-12 13:00:01.505 0.0 
2016-09-12 13:00:06.017 1.0 
2016-09-12 13:00:07.233 0.0 
2016-09-12 13:00:08.256 1.0 

Was ist der effizienteste Weg, dies zu tun? Ich sehe nichts nützliches für Zeitbereichsausschlüsse in der API.

Antwort

11

Sie können pd.merge_asof verwendet werden, die eine neue Aufnahme mit 0.19.0 beginnend und akzeptiert auch eine Toleranz Argument +/- übereinstimmen, die Menge an Zeitintervall angegeben wird.

# Assuming time to be set as the index axis for both df's 
df1.reset_index(inplace=True) 
df2.reset_index(inplace=True) 

df2.loc[pd.merge_asof(df2, df1, on='time', tolerance=pd.Timedelta('1s')).isnull().any(1)] 

enter image description here

Man beachte, dass standardmäßig Anpassung in der Rückwärtsrichtung durchgeführt wird, was bedeutet, dass die Auswahl in dem rechten Datenrahmen (df1), deren in der letzten Zeile auftritt "on" Taste (die "time" ist) ist kleiner oder gleich der linken Taste (df2). Daher erstreckt sich der Parameter tolerance nur in dieser Richtung (rückwärts), was zu einem Bereich von führt.

beide nach vorn haben sowie rückwärts Lookups möglich, diese mit 0.20.0 beginnend durch den Einsatz von direction='nearest' Argument erreicht werden kann und es im Funktionsaufruf enthält. Aus diesem Grund wird die tolerance auch beide Wege erweitert, was zu einer Bandbreite der Übereinstimmung führt.

+1

schlug mich zu ihm ... – piRSquared

+2

haha.Remember über @ MaxU Kommentar vor ein paar Tagen über seine Toleranz Param. –

1

Eine Möglichkeit, es zu tun wäre, über Zeitindizierung Lookup (sowohl Zeit unter der Annahme, Spalten sind Indizes):

td = pd.to_timedelta(1, unit='s') 
df2.apply(lambda row: df1[row.name - td:row.name].size > 0, axis=1) 
4

ähnliche Idee wie @Nickil Maveli, aber reindex einen Booleschen Indexer bauen mit:

df2 = df2[df1.reindex(df2.index, method='nearest', tolerance=pd.Timedelta('1s')).isnull()] 

Die resultierende Ausgabe:

time 
2016-09-12 13:00:01.505 0.0 
2016-09-12 13:00:06.017 1.0 
2016-09-12 13:00:07.233 0.0 
2016-09-12 13:00:08.256 1.0 
Verwandte Themen