在此问题中,我试图了解何时应基于“值”生成警报。
如果先前的5个值大于10,则创建警报。警报将继续保持活动状态,直到该值降至7.5以下。现在,一旦警报不再处于活动状态,并且到达前5个值都超过10的阶段,便会再次创建警报。
这是我用来执行此操作的逻辑:
NUM_PREV_ROWS = 5
PREV_5_THRESHOLD = 10.0
PREV_THRESHOLD = 7.5
d = {'device': ['a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','b','b','b','b','b',
'b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b'] ,
'value': [11,11,11,11,11,11,11,8,9,11,11,11,11,11,8,9,6,11,11,11,11,11,11,11,11,11,11,11,11,8,9,11,11,11,11,11,8,9,6,11,11,11,11,11]}
df = pd.DataFrame(data=d)
df['prev>10'] = df['value']>PREV_5_THRESHOLD
df['prev5>10'] = df['prev>10'].rolling(NUM_PREV_ROWS).sum()
df['prev>7.5'] = df['value']>PREV_THRESHOLD
alert = False
alert_series = []
for row in df.iterrows():
if row[1]['prev5>10']==NUM_PREV_ROWS:
alert = True
if row[1]['prev>7.5']==False:
alert = False
alert_series.append(alert)
df['alert'] = alert_series
问题是,遇到新设备时,循环应重新启动(在这种情况下,应首先为A运行,然后在遇到该设备时在B之上运行)。我该怎么办?
这是具有当前逻辑的输出:
print(df)
value prev>10 prev5>10 prev>7.5 alert
a 11 True NaN True False
a 11 True NaN True False
a 11 True NaN True False
a 11 True NaN True False
a 11 True 5.0 True True
a 11 True 5.0 True True
a 11 True 5.0 True True
a 8 False 4.0 True True
a 9 False 3.0 True True
a 11 True 3.0 True True
a 11 True 3.0 True True
a 11 True 3.0 True True
a 11 True 4.0 True True
a 11 True 5.0 True True
a 8 False 4.0 True True
a 9 False 3.0 True True
a 6 False 2.0 False False
a 11 True 2.0 True False
a 11 True 2.0 True False
a 11 True 3.0 True False
a 11 True 4.0 True False
a 11 True 5.0 True True
b 11 True 5.0 True True
b 11 True 5.0 True True
b 11 True 5.0 True True
b 11 True 5.0 True True
b 11 True 5.0 True True
b 11 True 5.0 True True
b 11 True 5.0 True True
b 8 False 4.0 True True
b 9 False 3.0 True True
b 11 True 3.0 True True
b 11 True 3.0 True True
b 11 True 3.0 True True
b 11 True 4.0 True True
b 11 True 5.0 True True
b 8 False 4.0 True True
b 9 False 3.0 True True
b 6 False 2.0 False False
b 11 True 2.0 True False
b 11 True 2.0 True False
b 11 True 3.0 True False
b 11 True 4.0 True False
b 11 True 5.0 True True
感谢所有帮助!
答案 0 :(得分:0)
我不确定这是否是最好的方法,但是使用groupby
重置循环又如何呢?
def f(df):
alert = False
alert_series = []
for row in df.iterrows():
if row[1]['prev5>10']==NUM_PREV_ROWS:
alert = True
if row[1]['prev>7.5']==False:
alert = False
alert_series.append(alert)
return pd.DataFrame({'alert': alert_series})
df['alert'] = df.groupby("device").apply(f).reset_index(drop=True)
答案 1 :(得分:0)
首先,您需要一个对块进行解析的方法。我尝试了另一种矢量化方法:
def larger_than_threshold(
data,
previous_5_threshold=PREV_5_THRESHOLD,
amount=NUM_PREV_ROWS,
previous_threshold=PREV_THRESHOLD,
):
prev5_over_limit = (
((data > previous_5_threshold).rolling(amount).sum() == amount)
.astype(int)
.diff()
== 1
).replace({False: None})
prev_under_threshold = (data < previous_threshold)
prev5_over_limit[prev_under_threshold] = False
return prev5_over_limit.fillna(method="ffill").fillna(False)
这将接受您的value
系列数据
您也可以在这里使用迭代方法。
然后,您可以使用groupby.transform
将其应用于每个单独的设备
df["alert"] = df.groupby("device").transform(larger_than_threshold)