How to check between which threshold level does a value lie in?2019 Community Moderator ElectionHow to drop rows of Pandas DataFrame whose value in certain columns is NaNFiltering top-level categories in hierarchical Pandas Dataframe using lower-level dataHas anyone had problems applying Pandas's 'any()' method to a large DataFrame? What's going on?How to check if any value is NaN in a Pandas DataFramePandas checking if values in multiple column exists in other columnsFill the column using the previous value in the column and some calculations in pandasWhat is the difference between unicodedata.digit and unicodedata.numeric?Colors for pandas bar chartAssigning a column to a SparseDataFramePython Pandas ordering strings

Turning a hard to access nut?

Friend wants my recommendation but I don't want to

CLI: Get information Ubuntu releases

Why I don't get the wanted width of tcbox?

If I cast the Enlarge/Reduce spell on an arrow, what weapon could it count as?

Hackerrank All Women's Codesprint 2019: Name the Product

Is VPN a layer 3 concept?

Is this Pascal's Matrix?

What is the tangent at a sharp point on a curve?

What is the reasoning behind standardization (dividing by standard deviation)?

10 year ban after applying for a UK student visa

Print a physical multiplication table

How do researchers send unsolicited emails asking for feedback on their works?

Is there any common country to visit for uk and schengen visa?

Why are there no stars visible in cislunar space?

What are the rules for concealing thieves' tools (or items in general)?

pipe commands inside find -exec?

label a part of commutative diagram

Would mining huge amounts of resources on the Moon change its orbit?

Can other pieces capture a threatening piece and prevent a checkmate?

Why doesn't the chatan sign the ketubah?

Someone scrambled my calling sign- who am I?

Help with identifying unique aircraft over NE Pennsylvania

Animating wave motion in water



How to check between which threshold level does a value lie in?



2019 Community Moderator ElectionHow to drop rows of Pandas DataFrame whose value in certain columns is NaNFiltering top-level categories in hierarchical Pandas Dataframe using lower-level dataHas anyone had problems applying Pandas's 'any()' method to a large DataFrame? What's going on?How to check if any value is NaN in a Pandas DataFramePandas checking if values in multiple column exists in other columnsFill the column using the previous value in the column and some calculations in pandasWhat is the difference between unicodedata.digit and unicodedata.numeric?Colors for pandas bar chartAssigning a column to a SparseDataFramePython Pandas ordering strings










3















I have a dataframe having columns looking like this (having 1400 unique contextIDs and 28 different IndicatorIDs):



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


The actual_values column is the real value read by a sensor of a machine. The threshold_values columns contain various thresholds defined for various indicators (in the IndicatorID column), depending on which an alarm will be raised if the value crosses a certain limit.



Example: If a value in actual_values lies between the threshold_values defined for alarm level -1 and +1 the product is not defective. But, if the value lies between -1 and -2, an alarm of -1 (since it has crossed the threshold that was defined for -1) must be raised and if the value lies between +1 and +2, an alarm of +1 must be raised, and so on. In the end, the biggest alarm level must be assigned to the ContextID, meaning, if one indicator has raised an alarm of +1 and a second indicator has raised an alarm of -2, the alarm level of -2 must be considered greater and assigned as the final alarm to that ContextID (preferably in a new column).



I wanted some help in implementing this concept. I would like to know if such an implementation can be coded.



I am trying to implement it using 2 different for loops, one for all the ContextIDs and other for the IndicatorIDs, but somehow I am failing in coming up with the logic that can achieve this task.



I would be grateful for help and guidance.



Thanks



Edit 1:



Example:



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


The thresh_value of 610.9839 belongs to a different IndicatorID (204516), but this value is being used to compute the alarm level of IndicatorID (204515)










share|improve this question




























    3















    I have a dataframe having columns looking like this (having 1400 unique contextIDs and 28 different IndicatorIDs):



    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


    The actual_values column is the real value read by a sensor of a machine. The threshold_values columns contain various thresholds defined for various indicators (in the IndicatorID column), depending on which an alarm will be raised if the value crosses a certain limit.



    Example: If a value in actual_values lies between the threshold_values defined for alarm level -1 and +1 the product is not defective. But, if the value lies between -1 and -2, an alarm of -1 (since it has crossed the threshold that was defined for -1) must be raised and if the value lies between +1 and +2, an alarm of +1 must be raised, and so on. In the end, the biggest alarm level must be assigned to the ContextID, meaning, if one indicator has raised an alarm of +1 and a second indicator has raised an alarm of -2, the alarm level of -2 must be considered greater and assigned as the final alarm to that ContextID (preferably in a new column).



    I wanted some help in implementing this concept. I would like to know if such an implementation can be coded.



    I am trying to implement it using 2 different for loops, one for all the ContextIDs and other for the IndicatorIDs, but somehow I am failing in coming up with the logic that can achieve this task.



    I would be grateful for help and guidance.



    Thanks



    Edit 1:



    Example:



    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


    The thresh_value of 610.9839 belongs to a different IndicatorID (204516), but this value is being used to compute the alarm level of IndicatorID (204515)










    share|improve this question


























      3












      3








      3








      I have a dataframe having columns looking like this (having 1400 unique contextIDs and 28 different IndicatorIDs):



      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


      The actual_values column is the real value read by a sensor of a machine. The threshold_values columns contain various thresholds defined for various indicators (in the IndicatorID column), depending on which an alarm will be raised if the value crosses a certain limit.



      Example: If a value in actual_values lies between the threshold_values defined for alarm level -1 and +1 the product is not defective. But, if the value lies between -1 and -2, an alarm of -1 (since it has crossed the threshold that was defined for -1) must be raised and if the value lies between +1 and +2, an alarm of +1 must be raised, and so on. In the end, the biggest alarm level must be assigned to the ContextID, meaning, if one indicator has raised an alarm of +1 and a second indicator has raised an alarm of -2, the alarm level of -2 must be considered greater and assigned as the final alarm to that ContextID (preferably in a new column).



      I wanted some help in implementing this concept. I would like to know if such an implementation can be coded.



      I am trying to implement it using 2 different for loops, one for all the ContextIDs and other for the IndicatorIDs, but somehow I am failing in coming up with the logic that can achieve this task.



      I would be grateful for help and guidance.



      Thanks



      Edit 1:



      Example:



      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


      The thresh_value of 610.9839 belongs to a different IndicatorID (204516), but this value is being used to compute the alarm level of IndicatorID (204515)










      share|improve this question
















      I have a dataframe having columns looking like this (having 1400 unique contextIDs and 28 different IndicatorIDs):



      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


      The actual_values column is the real value read by a sensor of a machine. The threshold_values columns contain various thresholds defined for various indicators (in the IndicatorID column), depending on which an alarm will be raised if the value crosses a certain limit.



      Example: If a value in actual_values lies between the threshold_values defined for alarm level -1 and +1 the product is not defective. But, if the value lies between -1 and -2, an alarm of -1 (since it has crossed the threshold that was defined for -1) must be raised and if the value lies between +1 and +2, an alarm of +1 must be raised, and so on. In the end, the biggest alarm level must be assigned to the ContextID, meaning, if one indicator has raised an alarm of +1 and a second indicator has raised an alarm of -2, the alarm level of -2 must be considered greater and assigned as the final alarm to that ContextID (preferably in a new column).



      I wanted some help in implementing this concept. I would like to know if such an implementation can be coded.



      I am trying to implement it using 2 different for loops, one for all the ContextIDs and other for the IndicatorIDs, but somehow I am failing in coming up with the logic that can achieve this task.



      I would be grateful for help and guidance.



      Thanks



      Edit 1:



      Example:



      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


      The thresh_value of 610.9839 belongs to a different IndicatorID (204516), but this value is being used to compute the alarm level of IndicatorID (204515)







      python-3.x pandas logic






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 7 at 18:05







      Kashyap Maheshwari

















      asked Mar 6 at 23:22









      Kashyap MaheshwariKashyap Maheshwari

      717




      717






















          1 Answer
          1






          active

          oldest

          votes


















          2














          Sure there is a way to do this. Probably better ways than the one below, but this will work.



          Initialize Data:



          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)


          I simplified the ContextID and IndicatorID, I also put some fake values in for the actual_values because yours all are within the proper range. We want to see what happens when they go outside of the proper range.



          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)


          We sort the dataframe, and then create thresh_high and alarm_high which are shifted versions of threshold_values and AlarmLevel



          Then we create a column that just shows whether or not the actual value landed inbetween the thresholds.



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


          )



          Lastly we filter the dataframe only for the times where the actual_values sat in the thresholds, and then we group by ContextId, IndicatorID, and insideThresh (this last one isn't really needed).
          We take the Alarm Level and apply a custom function telling it that if the minimum of the AlarmLevel from where it breached is negative, take the level up 1, otherwise take the minimum.






          share|improve this answer

























          • Of course, shifting the threshold and the alarm level value works. I wonder why didn't I think of this simple solution. Thanks, Matt for helping me :)

            – Kashyap Maheshwari
            Mar 7 at 10:09











          • Hey @Matt, I had a small query. Could you explain what do you mean when you say if the minimum of the AlarmLevel from where it breached is negative, take the level up 1, otherwise take the minimum. ? Thanks

            – Kashyap Maheshwari
            Mar 7 at 16:26






          • 1





            Yeah- so the way I did it it would show you the threshold band that it fell in. If it fell in -2, -1 you want to call it -1 because it passed -1, if it fell in 1,2 you want to call it 1. In the alarmlevel column if you take the min of the first part of that (the -2, from the -2,-1 or the 1 from the 1,2) you’ll get the right alarm # for the 1,2 but the -2,-1 should have an alarm level of -1. So if it’s negative, meaning it grabs the -2, add one to it so it’s a -1 alarm

            – Matt W.
            Mar 7 at 17:29







          • 1





            yes, true I actually was typing out a response for that.

            – Matt W.
            Mar 8 at 23:54






          • 1





            I updated my code to have groupby shifts in there so it doesn't shift into another group. groupby shifts will shift within each specified group, and then it will have a null value at the end since there is nothing to shift beyond +3. So we fill that high thresh with infinity from numpy, and we call that thresh 4.

            – Matt W.
            Mar 9 at 0:04










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55033762%2fhow-to-check-between-which-threshold-level-does-a-value-lie-in%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          Sure there is a way to do this. Probably better ways than the one below, but this will work.



          Initialize Data:



          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)


          I simplified the ContextID and IndicatorID, I also put some fake values in for the actual_values because yours all are within the proper range. We want to see what happens when they go outside of the proper range.



          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)


          We sort the dataframe, and then create thresh_high and alarm_high which are shifted versions of threshold_values and AlarmLevel



          Then we create a column that just shows whether or not the actual value landed inbetween the thresholds.



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


          )



          Lastly we filter the dataframe only for the times where the actual_values sat in the thresholds, and then we group by ContextId, IndicatorID, and insideThresh (this last one isn't really needed).
          We take the Alarm Level and apply a custom function telling it that if the minimum of the AlarmLevel from where it breached is negative, take the level up 1, otherwise take the minimum.






          share|improve this answer

























          • Of course, shifting the threshold and the alarm level value works. I wonder why didn't I think of this simple solution. Thanks, Matt for helping me :)

            – Kashyap Maheshwari
            Mar 7 at 10:09











          • Hey @Matt, I had a small query. Could you explain what do you mean when you say if the minimum of the AlarmLevel from where it breached is negative, take the level up 1, otherwise take the minimum. ? Thanks

            – Kashyap Maheshwari
            Mar 7 at 16:26






          • 1





            Yeah- so the way I did it it would show you the threshold band that it fell in. If it fell in -2, -1 you want to call it -1 because it passed -1, if it fell in 1,2 you want to call it 1. In the alarmlevel column if you take the min of the first part of that (the -2, from the -2,-1 or the 1 from the 1,2) you’ll get the right alarm # for the 1,2 but the -2,-1 should have an alarm level of -1. So if it’s negative, meaning it grabs the -2, add one to it so it’s a -1 alarm

            – Matt W.
            Mar 7 at 17:29







          • 1





            yes, true I actually was typing out a response for that.

            – Matt W.
            Mar 8 at 23:54






          • 1





            I updated my code to have groupby shifts in there so it doesn't shift into another group. groupby shifts will shift within each specified group, and then it will have a null value at the end since there is nothing to shift beyond +3. So we fill that high thresh with infinity from numpy, and we call that thresh 4.

            – Matt W.
            Mar 9 at 0:04















          2














          Sure there is a way to do this. Probably better ways than the one below, but this will work.



          Initialize Data:



          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)


          I simplified the ContextID and IndicatorID, I also put some fake values in for the actual_values because yours all are within the proper range. We want to see what happens when they go outside of the proper range.



          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)


          We sort the dataframe, and then create thresh_high and alarm_high which are shifted versions of threshold_values and AlarmLevel



          Then we create a column that just shows whether or not the actual value landed inbetween the thresholds.



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


          )



          Lastly we filter the dataframe only for the times where the actual_values sat in the thresholds, and then we group by ContextId, IndicatorID, and insideThresh (this last one isn't really needed).
          We take the Alarm Level and apply a custom function telling it that if the minimum of the AlarmLevel from where it breached is negative, take the level up 1, otherwise take the minimum.






          share|improve this answer

























          • Of course, shifting the threshold and the alarm level value works. I wonder why didn't I think of this simple solution. Thanks, Matt for helping me :)

            – Kashyap Maheshwari
            Mar 7 at 10:09











          • Hey @Matt, I had a small query. Could you explain what do you mean when you say if the minimum of the AlarmLevel from where it breached is negative, take the level up 1, otherwise take the minimum. ? Thanks

            – Kashyap Maheshwari
            Mar 7 at 16:26






          • 1





            Yeah- so the way I did it it would show you the threshold band that it fell in. If it fell in -2, -1 you want to call it -1 because it passed -1, if it fell in 1,2 you want to call it 1. In the alarmlevel column if you take the min of the first part of that (the -2, from the -2,-1 or the 1 from the 1,2) you’ll get the right alarm # for the 1,2 but the -2,-1 should have an alarm level of -1. So if it’s negative, meaning it grabs the -2, add one to it so it’s a -1 alarm

            – Matt W.
            Mar 7 at 17:29







          • 1





            yes, true I actually was typing out a response for that.

            – Matt W.
            Mar 8 at 23:54






          • 1





            I updated my code to have groupby shifts in there so it doesn't shift into another group. groupby shifts will shift within each specified group, and then it will have a null value at the end since there is nothing to shift beyond +3. So we fill that high thresh with infinity from numpy, and we call that thresh 4.

            – Matt W.
            Mar 9 at 0:04













          2












          2








          2







          Sure there is a way to do this. Probably better ways than the one below, but this will work.



          Initialize Data:



          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)


          I simplified the ContextID and IndicatorID, I also put some fake values in for the actual_values because yours all are within the proper range. We want to see what happens when they go outside of the proper range.



          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)


          We sort the dataframe, and then create thresh_high and alarm_high which are shifted versions of threshold_values and AlarmLevel



          Then we create a column that just shows whether or not the actual value landed inbetween the thresholds.



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


          )



          Lastly we filter the dataframe only for the times where the actual_values sat in the thresholds, and then we group by ContextId, IndicatorID, and insideThresh (this last one isn't really needed).
          We take the Alarm Level and apply a custom function telling it that if the minimum of the AlarmLevel from where it breached is negative, take the level up 1, otherwise take the minimum.






          share|improve this answer















          Sure there is a way to do this. Probably better ways than the one below, but this will work.



          Initialize Data:



          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)


          I simplified the ContextID and IndicatorID, I also put some fake values in for the actual_values because yours all are within the proper range. We want to see what happens when they go outside of the proper range.



          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)


          We sort the dataframe, and then create thresh_high and alarm_high which are shifted versions of threshold_values and AlarmLevel



          Then we create a column that just shows whether or not the actual value landed inbetween the thresholds.



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


          )



          Lastly we filter the dataframe only for the times where the actual_values sat in the thresholds, and then we group by ContextId, IndicatorID, and insideThresh (this last one isn't really needed).
          We take the Alarm Level and apply a custom function telling it that if the minimum of the AlarmLevel from where it breached is negative, take the level up 1, otherwise take the minimum.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 9 at 0:03

























          answered Mar 7 at 2:15









          Matt W.Matt W.

          2,196625




          2,196625












          • Of course, shifting the threshold and the alarm level value works. I wonder why didn't I think of this simple solution. Thanks, Matt for helping me :)

            – Kashyap Maheshwari
            Mar 7 at 10:09











          • Hey @Matt, I had a small query. Could you explain what do you mean when you say if the minimum of the AlarmLevel from where it breached is negative, take the level up 1, otherwise take the minimum. ? Thanks

            – Kashyap Maheshwari
            Mar 7 at 16:26






          • 1





            Yeah- so the way I did it it would show you the threshold band that it fell in. If it fell in -2, -1 you want to call it -1 because it passed -1, if it fell in 1,2 you want to call it 1. In the alarmlevel column if you take the min of the first part of that (the -2, from the -2,-1 or the 1 from the 1,2) you’ll get the right alarm # for the 1,2 but the -2,-1 should have an alarm level of -1. So if it’s negative, meaning it grabs the -2, add one to it so it’s a -1 alarm

            – Matt W.
            Mar 7 at 17:29







          • 1





            yes, true I actually was typing out a response for that.

            – Matt W.
            Mar 8 at 23:54






          • 1





            I updated my code to have groupby shifts in there so it doesn't shift into another group. groupby shifts will shift within each specified group, and then it will have a null value at the end since there is nothing to shift beyond +3. So we fill that high thresh with infinity from numpy, and we call that thresh 4.

            – Matt W.
            Mar 9 at 0:04

















          • Of course, shifting the threshold and the alarm level value works. I wonder why didn't I think of this simple solution. Thanks, Matt for helping me :)

            – Kashyap Maheshwari
            Mar 7 at 10:09











          • Hey @Matt, I had a small query. Could you explain what do you mean when you say if the minimum of the AlarmLevel from where it breached is negative, take the level up 1, otherwise take the minimum. ? Thanks

            – Kashyap Maheshwari
            Mar 7 at 16:26






          • 1





            Yeah- so the way I did it it would show you the threshold band that it fell in. If it fell in -2, -1 you want to call it -1 because it passed -1, if it fell in 1,2 you want to call it 1. In the alarmlevel column if you take the min of the first part of that (the -2, from the -2,-1 or the 1 from the 1,2) you’ll get the right alarm # for the 1,2 but the -2,-1 should have an alarm level of -1. So if it’s negative, meaning it grabs the -2, add one to it so it’s a -1 alarm

            – Matt W.
            Mar 7 at 17:29







          • 1





            yes, true I actually was typing out a response for that.

            – Matt W.
            Mar 8 at 23:54






          • 1





            I updated my code to have groupby shifts in there so it doesn't shift into another group. groupby shifts will shift within each specified group, and then it will have a null value at the end since there is nothing to shift beyond +3. So we fill that high thresh with infinity from numpy, and we call that thresh 4.

            – Matt W.
            Mar 9 at 0:04
















          Of course, shifting the threshold and the alarm level value works. I wonder why didn't I think of this simple solution. Thanks, Matt for helping me :)

          – Kashyap Maheshwari
          Mar 7 at 10:09





          Of course, shifting the threshold and the alarm level value works. I wonder why didn't I think of this simple solution. Thanks, Matt for helping me :)

          – Kashyap Maheshwari
          Mar 7 at 10:09













          Hey @Matt, I had a small query. Could you explain what do you mean when you say if the minimum of the AlarmLevel from where it breached is negative, take the level up 1, otherwise take the minimum. ? Thanks

          – Kashyap Maheshwari
          Mar 7 at 16:26





          Hey @Matt, I had a small query. Could you explain what do you mean when you say if the minimum of the AlarmLevel from where it breached is negative, take the level up 1, otherwise take the minimum. ? Thanks

          – Kashyap Maheshwari
          Mar 7 at 16:26




          1




          1





          Yeah- so the way I did it it would show you the threshold band that it fell in. If it fell in -2, -1 you want to call it -1 because it passed -1, if it fell in 1,2 you want to call it 1. In the alarmlevel column if you take the min of the first part of that (the -2, from the -2,-1 or the 1 from the 1,2) you’ll get the right alarm # for the 1,2 but the -2,-1 should have an alarm level of -1. So if it’s negative, meaning it grabs the -2, add one to it so it’s a -1 alarm

          – Matt W.
          Mar 7 at 17:29






          Yeah- so the way I did it it would show you the threshold band that it fell in. If it fell in -2, -1 you want to call it -1 because it passed -1, if it fell in 1,2 you want to call it 1. In the alarmlevel column if you take the min of the first part of that (the -2, from the -2,-1 or the 1 from the 1,2) you’ll get the right alarm # for the 1,2 but the -2,-1 should have an alarm level of -1. So if it’s negative, meaning it grabs the -2, add one to it so it’s a -1 alarm

          – Matt W.
          Mar 7 at 17:29





          1




          1





          yes, true I actually was typing out a response for that.

          – Matt W.
          Mar 8 at 23:54





          yes, true I actually was typing out a response for that.

          – Matt W.
          Mar 8 at 23:54




          1




          1





          I updated my code to have groupby shifts in there so it doesn't shift into another group. groupby shifts will shift within each specified group, and then it will have a null value at the end since there is nothing to shift beyond +3. So we fill that high thresh with infinity from numpy, and we call that thresh 4.

          – Matt W.
          Mar 9 at 0:04





          I updated my code to have groupby shifts in there so it doesn't shift into another group. groupby shifts will shift within each specified group, and then it will have a null value at the end since there is nothing to shift beyond +3. So we fill that high thresh with infinity from numpy, and we call that thresh 4.

          – Matt W.
          Mar 9 at 0:04



















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55033762%2fhow-to-check-between-which-threshold-level-does-a-value-lie-in%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Save data to MySQL database using ExtJS and PHP [closed]2019 Community Moderator ElectionHow can I prevent SQL injection in PHP?Which MySQL data type to use for storing boolean valuesPHP: Delete an element from an arrayHow do I connect to a MySQL Database in Python?Should I use the datetime or timestamp data type in MySQL?How to get a list of MySQL user accountsHow Do You Parse and Process HTML/XML in PHP?Reference — What does this symbol mean in PHP?How does PHP 'foreach' actually work?Why shouldn't I use mysql_* functions in PHP?

          Compiling GNU Global with universal-ctags support Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Tags for Emacs: Relationship between etags, ebrowse, cscope, GNU Global and exuberant ctagsVim and Ctags tips and trickscscope or ctags why choose one over the other?scons and ctagsctags cannot open option file “.ctags”Adding tag scopes in universal-ctagsShould I use Universal-ctags?Universal ctags on WindowsHow do I install GNU Global with universal ctags support using Homebrew?Universal ctags with emacsHow to highlight ctags generated by Universal Ctags in Vim?

          Add ONERROR event to image from jsp tldHow to add an image to a JPanel?Saving image from PHP URLHTML img scalingCheck if an image is loaded (no errors) with jQueryHow to force an <img> to take up width, even if the image is not loadedHow do I populate hidden form field with a value set in Spring ControllerStyling Raw elements Generated from JSP tagds with Jquery MobileLimit resizing of images with explicitly set width and height attributeserror TLD use in a jsp fileJsp tld files cannot be resolved