Сначала мы получаем абсолютную разницу для столбцов, а затем cumsum()
.
Предполагая, что если значение не изменится, совокупная сумма различий останется постоянной, мы можем использовать pandas .shift()
.
Мы должны сравнить каждое значение в зоне 1 с 4 строками выше. Аналогично зоне 2.
import pandas as pd
import numpy as np
import datetime
# Generate some random data
ts_index = pd.date_range("1/1/2019", periods=24, freq="1H")
v1 = [random.randint(1, 100) for i in range(24)]
v2 = [2] * 24
v3 = [2, 2, 2, 2, 4, 4, 0, 2, 2, 1, 9, 2, 4, 1, 2, 2, 0, 2, 1, 8, 1, 7, 3, 5]
df = pd.DataFrame({"v1": v1, "v2": v2, "v3": v3}, index=ts_index)
df1 = df.diff().fillna(0)
# Add hour and time of day to create flag
df['Hour'] = df.index.hour
df['Flag'] = np.where((df['Hour'] <= 8) | (df['Hour'] >= 18), 'Zone1', 'Zone2')
df1['Flag'] = np.where((df['Hour'] <= 8) | (df['Hour'] >= 18), 'Zone1', 'Zone2')
df1[["v1", "v2","v3"]] = np.abs(df1[["v1", "v2","v3"]])
df1[["v1", "v2","v3"]] = df1.groupby("Flag")["v1", "v2","v3"].cumsum()
columns = ["v1","v2","v3"]
z1_p = 3
z2_p = 1
for col in columns:
df["Flag_"+col] = (np.array(df1[col].shift(z1_p) == df1[col]) & np.array(df1["Flag"] == "Zone1")) | \
(np.array(df1[col].shift(z2_p) == df1[col]) & np.array(df1["Flag"] == "Zone2"))
for element in df[df["Flag_"+col] == True].index:
if df.loc[element]["Flag"] == "Zone1":
for i in range(1,4):
a = a.append(pd.Index([element - datetime.timedelta(hours=i)]))
else:
a = a.append(pd.Index([element - datetime.timedelta(hours=1)]))
df.at[a,"Flag_"+col] = True
df
Вывод:
v1 v2 v3 Hour Flag Flag_v1 Flag_v2 Flag_v3
2019-01-01 00:00:00 31 2 2 0 Zone1 False True True
2019-01-01 01:00:00 93 2 2 1 Zone1 False True True
2019-01-01 02:00:00 48 2 2 2 Zone1 False True True
2019-01-01 03:00:00 56 2 2 3 Zone1 False True True
2019-01-01 04:00:00 9 2 4 4 Zone1 False True False
2019-01-01 05:00:00 75 2 4 5 Zone1 False True False
2019-01-01 06:00:00 29 2 0 6 Zone1 False True False
2019-01-01 07:00:00 61 2 2 7 Zone1 False True False
2019-01-01 08:00:00 64 2 2 8 Zone1 False True False
2019-01-01 09:00:00 82 2 1 9 Zone2 False True False
2019-01-01 10:00:00 13 2 9 10 Zone2 False True False
2019-01-01 11:00:00 97 2 2 11 Zone2 False True False
2019-01-01 12:00:00 74 2 4 12 Zone2 False True False
2019-01-01 13:00:00 26 2 1 13 Zone2 False True False
2019-01-01 14:00:00 77 2 2 14 Zone2 False True True
2019-01-01 15:00:00 39 2 2 15 Zone2 False True True
2019-01-01 16:00:00 79 2 0 16 Zone2 False True False
2019-01-01 17:00:00 35 2 2 17 Zone2 False True False
2019-01-01 18:00:00 65 2 1 18 Zone1 False True False
2019-01-01 19:00:00 74 2 8 19 Zone1 False True False
2019-01-01 20:00:00 72 2 1 20 Zone1 False True False
2019-01-01 21:00:00 23 2 7 21 Zone1 False True False
2019-01-01 22:00:00 28 2 3 22 Zone1 False True False
2019-01-01 23:00:00 59 2 5 23 Zone1 False True False