Reputation: 12107
This is a follow-on to my previous question: detecting value crossing between columns in Pandas
Let's assume I have two columns, df['a']
and df['b']
, called 'a' and 'b' here to simplify
In the previous question, I was trying to detect indices where: a[i - 1] < b[i] and a[i] >= b[i]
now, I am trying to track two changes:
a[i - 1] < b[i] and a[i] >= b[i]
and
a[i - 1] >= b[i] and a[i] < b[i]
and create a column with a value set based on the LAST change that occurred.
Here is some pseudo code:
state = 0
result = []
for i in myIndex:
if a[i - 1] < b[i] and a[i] >= b[i]:
state = 1
elif a[i - 1] >= b[i] and a[i] < b[i]:
state = 0
result.append(state)
is there an idiomatic (non-looping) way to achieve this in Pandas?
Edit:
I realize this question has caused some confusion, so I didn't word it properly. An example here:
Let's assume I have two columns for the outputs of the two conditions I'm tracking:
cond_A cond_B
false false
false true
false false
false false
true false
false false
then the output should be (if we set 0 and 1 as output values):
cond_A cond_B output
false false 0
false true 1
false false 1
false false 1
true false 0
false false 0
so, if both conditions are false, we reuse the last state, if a condition is true, we set the state.
Upvotes: 1
Views: 117
Reputation: 30920
this is the equation of a RS flip flop: https://en.wikipedia.org/wiki/Flip-flop_(electronics)
using the example given as a dataframe:
print(df)
cond_A cond_B
0 False False
1 False True
2 False False
3 False False
4 True False
5 False False
UPDATE
df['state']=df.any(axis=1).where(df['cond_B'].cumsum().ge(1),0).cumsum()%2
print(df)
cond_A cond_B state
0 False False 0
1 False True 1
2 False False 1
3 False False 1
4 True False 0
5 False False 0
If you have two independent series
(cond_A | cond_B).where(cond_B.cumsum().ge(1),0).cumsum()%2
Upvotes: 1
Reputation: 5757
You can try
>>> df['c'] = pd.Series((df.a.shift(-1) < df.b) & (df.a >= df.b)).replace({False : 0, True : 1})
>>> df
a b c
0 8 17 0
1 2 86 0
2 93 42 0
3 49 1 0
4 35 62 0
5 3 39 0
6 25 21 0
7 54 24 1
8 3 77 0
9 41 42 0
Upvotes: 0