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
I have a dataframe having columns looking like this (having 1400 unique contextID
s and 28 different IndicatorID
s):
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 ContextID
s and other for the IndicatorID
s, 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
add a comment |
I have a dataframe having columns looking like this (having 1400 unique contextID
s and 28 different IndicatorID
s):
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 ContextID
s and other for the IndicatorID
s, 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
add a comment |
I have a dataframe having columns looking like this (having 1400 unique contextID
s and 28 different IndicatorID
s):
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 ContextID
s and other for the IndicatorID
s, 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
I have a dataframe having columns looking like this (having 1400 unique contextID
s and 28 different IndicatorID
s):
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 ContextID
s and other for the IndicatorID
s, 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
python-3.x pandas logic
edited Mar 7 at 18:05
Kashyap Maheshwari
asked Mar 6 at 23:22
Kashyap MaheshwariKashyap Maheshwari
717
717
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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.
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
|
show 4 more comments
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
|
show 4 more comments
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.
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
|
show 4 more comments
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.
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.
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
|
show 4 more comments
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
|
show 4 more comments
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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