[FIXED] Wie berechnet man die Gesamtzahl der 1-Stunden-Intervalle in einer Folge von Intervallen?

Ausgabe

Betrachten wir den folgenden Datenrahmen mit sortierten Zeitintervallen:

import pandas as pd
from io import StringIO

s="""start_time,end_time
2022-01-01 12:30:00,2022-01-01 12:45:00
2022-01-01 13:05:00,2022-01-01 13:50:00
2022-01-01 14:00:00,2022-01-01 14:20:00
2022-01-01 16:00:00,2022-01-01 16:45:00
2022-01-01 17:20:00,2022-01-01 17:35:00
2022-01-01 17:45:00,2022-01-01 18:30:00
2022-01-01 19:00:00,2022-01-01 19:25:00"""
df = pd.read_csv(StringIO(s), sep=",")
df.start_time = pd.to_datetime(df.start_time)
df.end_time = pd.to_datetime(df.end_time)

          start_time               end_time
0    2022-01-01 12:30:00    2022-01-01 12:45:00
1    2022-01-01 13:05:00    2022-01-01 13:50:00
2    2022-01-01 14:00:00    2022-01-01 14:20:00
3    2022-01-01 16:00:00    2022-01-01 16:45:00
4    2022-01-01 17:20:00    2022-01-01 17:35:00
5    2022-01-01 17:45:00    2022-01-01 18:30:00
6    2022-01-01 19:00:00    2022-01-01 19:25:00

Die Idee ist, dass ein 1-Stunden-Intervall im Grunde folgendermaßen berechnet wird: Wir beginnen mit dem start_timedes ersten Intervalls und fügen 1 Stunde hinzu.

Wenn der resultierende Zeitstempel innerhalb eines der folgenden Intervalle im Datenrahmen liegt, wiederholen wir den Vorgang, indem wir 1 Stunde zu diesem neuen Zeitstempel hinzufügen und so weiter.

Wenn der resultierende Zeitstempel jedoch nicht innerhalb, sondern zwischen zwei Intervallen liegt, fahren wir fort, indem wir 1 Stunde zum start_timenächsten Intervall addieren.

Die Eingabe wäre der obige Datenrahmen.

Der Prozess ist: Wir beginnen damit, 1 Stunde zum start_timeersten Intervall hinzuzufügen:

  1. 12:30 + 1H -> 13:30 (13:30 ist ein Zeitstempel, der innerhalb eines der verfügbaren Intervalle liegt. Insbesondere liegt es zwischen 13:05 – 13:50, was ein Intervall in unserem Datenrahmen ist. Wir werden , dann weiter ab 13:30).

  2. 13:30 + 1H -> 14:30 (14:30 ist in keinem unserer df-Intervalle enthalten – wir wählen das nächstgelegene start_timenach 14:30)

  3. 16:00 + 1H -> 17:00 (17:00 in keinem Intervall unseres Datenrahmens enthalten)

  4. 17:20 + 1H -> 18:20 (18:20 ist zwischen 17:45 – 18:30 enthalten, was auch ein Intervall ist, das wir in unserem Datenrahmen haben)

  5. 18:20 + 1H -> 19:20 (ist in unserem letzten Intervall enthalten)

  6. 19:20 + 1H -> 20:20 (wir haben die end_timeunseres letzten Intervalls erreicht oder überschritten (größer oder gleich), also hören wir auf). Wenn zum Beispiel der letzte end_timeim Datenrahmen 19:20:00 statt 19:25:00 war, hätten wir im vorherigen Schritt aufgehört (da wir einen Zeitstempel erreicht haben, der größer oder gleich dem allerletzten ist end_time).

Ausgabe: 6 (Die Ausgabe im alternativen Fall, dass das end_timeAllerletzte gleich 19:20:00 ist, wäre gleich 5 gewesen).

Die Ausgabe steht für die Gesamtzahl der Male, die der Vorgang des Hinzufügens von 1H wiederholt wurde.

Was den Code betrifft, habe ich daran gedacht, ihn vielleicht .shift()irgendwie zu verwenden, aber ich bin mir nicht sicher, wie. Das Problem ist, dass wir, wenn der resultierende Zeitstempel nicht zwischen einem verfügbaren Intervall liegt, nach dem nächstgelegenen folgenden suchen sollten start_time.

Lösung

Es ist unwahrscheinlich, dass eine Vektorisierung (dh Parallelisierung) möglich ist, da der Prozess in jedem Schritt vom Ergebnis der Berechnungen in den vorherigen Schritten abhängt. Die Lösung wird in jedem Fall eine Art Iteration sein. Und die Geschwindigkeit der Arbeit hängt in erster Linie von dem Algorithmus ab, mit dem Sie arbeiten möchten.

Es scheint mir, dass ein guter Algorithmus darin bestünde, zu sehen, ob die end_timeund start_timebenachbarter Datensätze in denselben Stundenschritt fallen, als ob wir die Länge nach Stunden ab einem bestimmten Punkt messen würden. Dazu können wir eine ganzzahlige Division verwenden:

import pandas as pd
from io import StringIO

s = """start_time,end_time
2022-01-01 12:30:00,2022-01-01 12:45:00
2022-01-01 13:05:00,2022-01-01 13:50:00
2022-01-01 14:00:00,2022-01-01 14:20:00
2022-01-01 16:00:00,2022-01-01 16:45:00
2022-01-01 17:20:00,2022-01-01 17:35:00
2022-01-01 17:45:00,2022-01-01 18:30:00
2022-01-01 19:00:00,2022-01-01 19:25:00"""

df = pd.read_csv(StringIO(s), parse_dates=[0, 1])

data = df.to_numpy().flatten()
start = data[0]
step = pd.Timedelta(1, 'H')   # hour as a unit of length
count = 0
for x, y in data[1:-1].reshape(-1, 2):
    # x is previous end_time
    # y is next start_time
    length = (x-start) // step + 1
    if start + step*length < y:
        count += length
        start = y
integer, decimal = divmod((data[-1] - start) / step, 1)
count += integer if decimal == 0 else integer+1

print(f'{count = }')


Beantwortet von –
Vitalizzare


Antwort geprüft von –
Timothy Miller (FixError Admin)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like