python-3.x - 如何检查某个值位于哪个阈值水平之间?

标签 python-3.x pandas logic

我有一个数据框,其列如下所示(具有 1400 个唯一的 contextID 和 28 个不同的 IndicatorID ):

ContextID   IndicatorID threshold_values    AlarmLevel  actual_values
7289972        204511   -6.10904                 -1         0
7289972        204511   -12.1848                 -2         0
7289972        204511   -18.2606                 -3         0
7289972        204511   18.19404                  1         0
7289972        204511   24.2698                   2         0
7289972        204511   30.34557                  3         0
7289972        204512   89.94568                  1        64.114
7289972        204512   104.2932                  2        64.114
7289972        204512   118.6407                  3        64.114
7289972        204512   32.55574                 -1        64.114
7289972        204512   18.20825                 -2        64.114
7289972        204512   3.860765                 -3        64.114
7289998        204511   -6.10904                 -1           1
7289998        204511   -12.1848                 -2           1
7289998        204511   -18.2606                 -3           1
7289998        204511   18.19404                  1           1
7289998        204511   24.2698                   2           1
7289998        204511   30.34557                  3           1
7289998        204512   89.94568                  1        64.111
7289998        204512   104.2932                  2        64.111
7289998        204512   118.6407                  3        64.111
7289998        204512   32.55574                 -1        64.111
7289998        204512   18.20825                 -2        64.111
7289998        204512   3.860765                 -3        64.111

actual_values 列是机器传感器读取的实际值。 threshold_values 列包含为各种指标(在 IndicatorID 列中)定义的各种阈值,具体取决于值超过特定限制时将引发的警报。

示例:如果 actual_values 中的值位于为警报级别 -1 和 +1 定义的 threshold_values 之间,则产品没有缺陷。但是,如果该值介于 -1 和 -2 之间,则必须发出 -1 警报(因为它已超过为 -1 定义的阈值),如果该值介于 +1 和 +2 之间,则必须发出警报必须提高+1,依此类推。最后,必须将最大警报级别分配给 ContextID ,这意味着,如果一个指标发出 +1 的警报,而第二个指标发出 -2 的警报,则必须将 -2 的警报级别视为更大,并且指定为该 ContextID 的最终警报(最好在新列中)。

我需要一些帮助来实现这个概念。我想知道是否可以编写这样的实现。

我试图使用 2 个不同的 for 循环来实现它,一个用于所有 ContextID ,另一个用于 IndicatorID ,但不知何故,我无法想出可以实现此任务的逻辑。

我将非常感谢您的帮助和指导。

谢谢

编辑1:

示例:

ContextID   IndicatorID threshold_values    AlarmLevel  actual_values   thresh_high alarm_high  insideThresh
7291899 204515  0.708226    -3  0.949486    0.742542    -2  FALSE
7291899 204515  0.742542    -2  0.949486    0.76        -1  FALSE
7291899 204515  0.76        -1  0.949486    0.914122     1  FALSE
7291899 204515  0.914122    1   0.949486    0.948438     2  FALSE
7291899 204515  0.948438    2   0.949486    0.982754     3  TRUE
7291899 204515  0.982754    3   0.949486    610.9839    -3  FALSE

thresh_value610.9839 属于不同的 IndicatorID (204516),但该值用于计算 IndicatorID (204515) 的警报级别

最佳答案

当然有办法做到这一点。可能比下面的方法更好,但这会起作用。

初始化数据:

import pandas as pd
import numpy as np

thresh = [-6.10904,
-12.1848,
-18.2606,
18.19404,
24.2698,
30.34557,
89.94568,
104.2932,
118.6407,
32.55574,
18.20825,
3.860765]

df = pd.DataFrame({'ContextID':[1]*12+[2]*12,
                   'IndicatorID':[5]*6+[6]*6+[7]*6+[8]*6,
                   'threshold_values':thresh*2,
                   'AlarmLevel':[-1, -2, -3, 1, 2, 3, 3, 2, 1, -1, -2, -3]*2,
                   'actual_values':[-17]*6+[64.114]*6+[26]*6+[64.111]*6})

我简化了ContextID和IndicatorID,我还为actual_values添加了一些假值,因为你们的值都在正确的范围内。我们想看看当它们超出适当范围时会发生什么。

df = df.sort_values(['ContextID', 'IndicatorID', 'AlarmLevel'])
df['thresh_high'] = df.groupby(['ContextID', 'IndicatorID'])['threshold_values'].shift(-1)
df['alarm_high'] = df.groupby(['ContextID', 'IndicatorID'])['AlarmLevel'].shift(-1)
df['thresh_high'] = df.thresh_high.fillna(np.Inf)
df['alarm_high'] = df.alarm_high.fillna(4)
df['insideThresh'] = (df.actual_values < df.thresh_high) & (df.actual_values > df.threshold_values)

我们对数据帧进行排序,然后创建 thresh_highalarm_high,它们是 threshold_valuesAlarmLevel 的移位版本

然后我们创建一个列,仅显示实际值是否落在阈值之间。

alarms = df.loc[df.insideThresh == True] \
            .groupby(['ContextID', 'IndicatorID', 'insideThresh'])['AlarmLevel'] \
            .apply(lambda x: x.min()+1 if x.min() < 0 else x.min()

)

最后,我们仅针对 actual_values 位于阈值的时间过滤数据帧,然后按 ContextId、IndicatorID 和 insideThresh 进行分组(实际上并不需要最后一个)。 我们获取警报级别并应用一个自定义函数,告诉它如果超出警报级别的最小值为负,则将级别提高 1,否则采用最小值。

关于python-3.x - 如何检查某个值位于哪个阈值水平之间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55033762/

相关文章:

Python Pandas 不读取 csv 文件的第一行

python - 带有结合了两个函数的 aggfunc 的数据透视表

python - 如何对 scipy.stats 测试实现多重测试

java - 用 java.lang.Boolean 和 switch 做三元逻辑

ruby-on-rails - 数据库中一个属性中一周的多天

python - 如何理解 Python 中 `None or False` 、 `False or None` 、 `None and False` 、 `False and None` 的结果?

string - 标记化文本中 ngram(字符串)的频率

python - 用于 bool 索引的 Pandas、loc 与非 loc

python - 将字符串解析为 int,下划线失败

python-3.x - 如何保存openCV分类器?