Reputation: 155
I have a dataframe like this.
import pandas as pd
df = pd.DataFrame({
'col': ['neutral', 'neutral', 'neutral', 'positive', 'positive', 'negative', 'neutral']})
Now I want to update 'col' such that i get a true when there is a change from positive to negative or the other way round and a false otherwise (ie consecutive equal values) and also a false when there is a change from positive/negative to neutral and the other way round.
I have tried several methods with grouby and transform but nothing works.
My desired output would be:
df = pd.DataFrame({
'col': ['False', 'False', 'False', 'False', 'False', 'True', 'False']})
Upvotes: 2
Views: 106
Reputation: 5359
A long expression that generates booleans based on your conditions:
(((df['col'] == 'positive') & (df['col'].shift(1) == 'negative')) | ((df['col'] == 'negative') & (df['col'].shift(1) == 'positive')))
This uses bitwise operators to say if the current position is positive and the one after is negative, True, or The current position is negative and the following is positive, True else return false.
>>> (((df['col'] == 'positive') & (df['col'].shift(1) == 'negative')) | ((df['col'] == 'negative') & (df['col'].shift(1) == 'positive')))
0 False
1 False
2 False
3 False
4 False
5 True
6 False
Name: col, dtype: bool
Either both of the first conditions must be met to return true, or both of the second conditions must be met to return true.
Upvotes: 0
Reputation: 51155
map
+ diff
Map positive and negative to 1
and -1
respectively, and neutral to 0
. When you take the difference of the series, the absolute value of the output every time positive and negative follow each other will be 2
, which you can easily check for, resulting in your desired outcome:
d = {'positive': 1, 'negative': -1, 'neutral': 0}
df.col.map(d).diff().abs().eq(2)
0 False
1 False
2 False
3 False
4 False
5 True
6 False
Name: col, dtype: bool
Upvotes: 1