Ich habe einige Zeitreihendaten als Pandas-Datenrahmen, der mit Beobachtungen um 15 Minuten nach der vollen Stunde und 45 Minuten nach der vollen Stunde (Zeitintervalle von 30 Minuten) beginnt und dann die Frequenz auf jede Minute ändert. Ich möchte die Daten neu abtasten, damit sie alle 30 Minuten, jeweils um 15 und 45 nach Ablauf der Stunden, für den gesamten Datenrahmen regelmäßig abgerufen werden.
Ich dachte an zwei Möglichkeiten, dies zu erreichen.
1. Filtern Sie einfach den Datenrahmen nach allen Beobachtungen bei 15 Minuten und 45 Minuten, wobei Sie die Zeitreihendaten als Spalte im Datenrahmen verwenden.
2. Stellen Sie den Index so ein, dass die Zeitreihendaten Teil eines Multi-Index sind (die 0. Ebene des Index ist die Wetterstation, die 1. Ebene ist die Zeit der Beobachtung) und verwenden Sie die Pandas-Funktion für Datum-Zeit-Zeitreihen, z als resample()
.
Der ursprüngliche Datenrahmen (Wetter) sieht folgendermaßen aus:
parsed_time Pressure Temp Hum
Station (index)
Bow 1 2018-04-15 14:15:00 1012 20.0 87
2 2018-04-15 14:45:00 1013 20.0 87
3 2018-04-15 15:15:00 1012 21.0 87
4 2018-04-15 15:45:00 1014 22.0 86
5 2018-04-15 16:00:00 1015 22.0 86
6 2018-04-15 16:01:00 1012 25.0 86
7 2018-04-15 16:02:00 1012 25.0 86
Stratford 8 2018-04-15 14:15:00 1011 18.0 87
9 2018-04-15 14:45:00 1011 18.0 87
10 2018-04-15 15:15:00 1012 18.0 87
11 2018-04-15 15:45:00 1014 19.0 86
12 2018-04-15 16:00:00 1014 19.0 86
13 2018-04-15 16:01:00 1015 19.0 86
14 2018-04-15 16:02:00 1016 20.0 86
15 2018-04-15 16:04:00 1016 20.0 86
Bei Methode 1 tritt das Problem auf, dass meine booleschen Auswahloperationen nicht wie erwartet zu funktionieren scheinen. Zum Beispiel
weather_test = weather[weather['parsed_time'].dt.minute == (15 & 45)]
gibt parsed_time-Werte wie folgt aus:
2018-04-15 14:13:00
2018-04-15 15:13:00
weather_test = weather[weather['parsed_time'].dt.minute == (15 | 45)]
ergibt parsed_time Werte wie diesen:
2018-04-15 14:47:00
2018-04-15 14:47:00
Ich kann nichts in den Dokumenten finden, um dieses Verhalten zu erklären. Was ich will, ist Druck, Temperatur, Luftfeuchtigkeit pro Station zu folgenden Zeiten:
2018-04-15 14:45:00
2018-04-15 15:15:00
2018-04-15 15:45:00
2018-04-15 16:15:00
und so weiter.
Bei Methode 2 dachte ich daran, die Daten erneut abzutasten, damit Beobachtungen, für die ich Minuten für Minuten Daten habe, durch den Mittelwert der letzten 30 Minuten ersetzt werden. Diese Funktionalität scheint nur zu funktionieren, wenn die Spalte parsed_time Teil des Index ist. Daher habe ich den folgenden Code verwendet, um parsed_time als Teil eines Multi-Index festzulegen:
weather.set_index('parsed_time', append=True, inplace=True)
weather.index.set_names('station', level=0, inplace=True)
weather = weather.reset_index(level=1, drop=True)
so erhalten Sie einen Datenrahmen, der wie folgt aussieht:
Pressure Temp Hum
Station parsed_time
Bow 2018-04-15 14:15:00 1012 20.0 87
2018-04-15 14:45:00 1013 20.0 87
2018-04-15 15:15:00 1012 21.0 87
2018-04-15 15:45:00 1014 22.0 86
2018-04-15 16:00:00 1015 22.0 86
2018-04-15 16:01:00 1012 25.0 86
2018-04-15 16:02:00 1012 25.0 86
Stratford 2018-04-15 14:15:00 1011 18.0 87
2018-04-15 14:45:00 1011 18.0 87
2018-04-15 15:15:00 1012 18.0 87
2018-04-15 15:45:00 1014 19.0 86
2018-04-15 16:00:00 1014 19.0 86
2018-04-15 16:01:00 1015 19.0 86
2018-04-15 16:02:00 1016 20.0 86
2018-04-15 16:04:00 1016 20.0 86
Beachten Sie, dass die Abtastung von Beobachtungen von 30 Minuten nach 15 und 45 nach 45 nach jeder Minute (z. B.: 01,: 02,: 14 usw.) und auch nach Station variiert - nicht alle Stationen haben jede Beobachtung.
Ich habe es versucht:
weather_test = weather.resample('30min', level=1).mean()
dies wird jedoch ohne Versatz neu abgetastet und die Stationsebene im Multi-Index wird ebenfalls entfernt.
Das gewünschte Ergebnis ist folgendes:
Pressure Temp Hum
Station parsed_time
Bow 2018-04-15 14:15:00 1012 20.0 87
2018-04-15 14:45:00 1013 20.0 87
2018-04-15 15:15:00 1012 21.0 87
2018-04-15 15:45:00 1014 22.0 86
2018-04-15 16:15:00 1013 24.0 86
Stratford 2018-04-15 14:15:00 1011 18.0 87
2018-04-15 14:45:00 1011 18.0 87
2018-04-15 15:15:00 1012 18.0 87
2018-04-15 15:45:00 1014 19.0 86
2018-04-15 16:15:00 1015 19.5 86
wobei die Beobachtungen von Minute zu Minute als Mittelwert über einen Zeitraum von 30 Minuten um: 15 und: 45 nach der vollen Stunde neu abgetastet wurden.
Es ist wichtig, die Station als Ebene im Multi-Index zu halten. Ich kann den Zeitindex nicht als eigenen Index verwenden, da sich die Werte für jede Station wiederholen (und nicht eindeutig sind).
Wir bedanken uns für jede Hilfe, da ich mit dieser schon eine Weile im Kreis bin. Vielen Dank!
Ich habe mir einige frühere Beiträge angesehen, darunter: Boolescher Filter mit einem Zeitstempelwert für einen Datenrahmen in Python
Wie runde ich die Datums Uhrzeitspalte auf die nächste Viertelstunde - /
und: Neuabtasten eines Pandas-Datenrahmens mit Zeitreihen mit mehreren Indizes was für etwas, das recht einfach sein sollte, etwas kompliziert erscheint ...
und die Dokumente: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.resample.html Danke!
Ausgehend von Ihrem vorletzten Datenrahmen (nach Verwendung von weather.reset_index(Station, inplace=True)
):
Station Pressure Temp Hum
parsed_time
2018-04-15 14:15:00 Bow 1012.0 20.0 87.0
2018-04-15 14:45:00 Bow 1013.0 20.0 87.0
2018-04-15 15:15:00 Bow 1012.0 21.0 87.0
2018-04-15 15:45:00 Bow 1014.0 22.0 86.0
2018-04-15 16:00:00 Bow 1015.0 22.0 86.0
2018-04-15 16:01:00 Bow 1012.0 25.0 86.0
2018-04-15 16:02:00 Bow 1012.0 25.0 86.0
2018-04-15 14:15:00 Stratford 1011.0 18.0 87.0
2018-04-15 14:45:00 Stratford 1011.0 18.0 87.0
2018-04-15 15:15:00 Stratford 1012.0 18.0 87.0
2018-04-15 15:45:00 Stratford 1014.0 19.0 86.0
2018-04-15 16:00:00 Stratford 1014.0 19.0 86.0
2018-04-15 16:01:00 Stratford 1015.0 19.0 86.0
2018-04-15 16:02:00 Stratford 1016.0 20.0 86.0
2018-04-15 16:04:00 Stratford 1016.0 20.0 86.0
sie können eine Kombination aus groupby
und resample
verwenden:
res = weather.groupby('Station').resample('30min').mean().reset_index('Station')
Standardmäßig wählt resample
die Bin-Intervalle [16:00, 16:30)
und [16:30, 17:00)
. Wie Sie bereits bemerkt haben, wird der Zeitindex ohne Versatz neu abgetastet, aber Sie können ihn später mit DateOffset
wieder hinzufügen:
res.index = res.index + pd.DateOffset(minutes=15)
was ergibt:
Station Pressure Temp Hum
parsed_time
2018-04-15 14:15:00 Bow 1012.00 20.0 87.0
2018-04-15 14:45:00 Bow 1013.00 20.0 87.0
2018-04-15 15:15:00 Bow 1012.00 21.0 87.0
2018-04-15 15:45:00 Bow 1014.00 22.0 86.0
2018-04-15 16:15:00 Bow 1013.00 24.0 86.0
2018-04-15 14:15:00 Stratford 1011.00 18.0 87.0
2018-04-15 14:45:00 Stratford 1011.00 18.0 87.0
2018-04-15 15:15:00 Stratford 1012.00 18.0 87.0
2018-04-15 15:45:00 Stratford 1014.00 19.0 86.0
2018-04-15 16:15:00 Stratford 1015.25 19.5 86.0
Alternativ können Sie den Offset auch direkt in der resample-Methode angeben:
weather.groupby('Station').resample('30min', loffset=pd.Timedelta('15min')).mean()
Ich habe Ihre Daten nicht, daher kann ich dies nicht direkt untersuchen, aber versuchen Sie die folgende Syntax für die Option, die Sie als Option 1 bezeichnen:
weather_test = weather[(weather['parsed_time'].dt.minute == 15) | (weather['parsed_time'].dt.minute == 45)]
Wenn Sie ohne Index beginnen (mit Ausnahme eines Zeilenindex), können Sie Folgendes ausführen:
# Create a rounded timestamp
df['parsed_time_rounded'] = (df['parsed_time'] - pd.Timedelta('15min')).dt.round('30min') + pd.Timedelta('15min')
# Group by the station, and the rounded timestamp instead of the raw timestamp
df.groupby(['Station', 'parsed_time_rounded']).mean()