Viktor.w
Viktor.w

Reputation: 2297

Pandas: series of True or False in a column, select in another column the value when there is a True

My dataframe looks like this:

 price          High_cross
 0.00224311     False
 0.00224473     False
 0.00224422     False
 0.00224697     True
 0.00224899     True
 0.00224668     True
 0.00224967     True
 0.00224967     True
 0.00224983     True
 0.00225143     False

And what I need to do is loop on the column High_cross, when there is a True select the related price and compare it with the price the final True of the series. If the first price is below the second price, notify it in a new column movement by True. In this example it should look at something like that:

 price          High_cross  Movement
 0.00224311     False
 0.00224473     False
 0.00224422     False
 0.00224697     True         True
 0.00224899     True
 0.00224668     True
 0.00224967     True
 0.00224967     True
 0.00224983     True
 0.00225143     False

(because 0.00224983 is bigger than 0.00224697)!

I tried to play with the index but I am relatively stuck... any solution/idea? Thanks

Upvotes: 2

Views: 343

Answers (2)

ChKl
ChKl

Reputation: 147

I'm not sure if I understood completely what your goal is here. I assuemd:

  1. Select price if respective High_Cross == True
  2. Compare the price to the last price where High_Cross == True
  3. Set respective Movement = True if current price < last price[High_Cross == True]

but the following code achieves what I think you want:

import numpy as np
np.random.seed(5)
X = np.random.choice(range(10), size=10, replace=True).tolist()
Y = np.random.randint(2, size=10)
Y = [bool(y) for y in Y]

lst = []
movement = []
# Extract list of all true values
for price,cross in zip(X,Y):
    # Create list of tuples
    cross == True and lst.append((price,cross)) # If one liner avoiding the otherwise mandatory else statement

# Now do the work itself
for price,cross in zip(X,Y):
    movement.append(True) if cross == True and price > lst[-1][0] else movement.append(False)
    print("Price="+str(price)+", High_Cross="+str(cross)+", Movement="+str(movement[-1]))

Produces:

Price=3, High_Cross=True, Movement=True
Price=6, High_Cross=False, Movement=False
Price=6, High_Cross=True, Movement=True
Price=0, High_Cross=True, Movement=False
Price=9, High_Cross=True, Movement=True
Price=8, High_Cross=True, Movement=True
Price=4, High_Cross=False, Movement=False
Price=7, High_Cross=True, Movement=True
Price=0, High_Cross=False, Movement=False
Price=0, High_Cross=True, Movement=False

`

Upvotes: 0

anky
anky

Reputation: 75080

Consider the below df:

       price  High_cross
0   0.002243       False
1   0.002245       False
2   0.002244       False
3   0.002247        True
4   0.002249        True
5   0.002247        True
6   0.002250        True
7   0.002250        True
8   0.002250        True
9   0.002251       False
10  0.002251        True
11  0.002250        True

Use:

df['identifier']=(df.High_cross.ne(df.High_cross.shift())).cumsum()
df['Movement']=df[df.High_cross].groupby('identifier')['price'].\
                       transform(lambda x: x.iloc[0]<x.iloc[-1])
print(df.drop('identifier',1))

       price  High_cross Movement
0   0.002243       False      NaN
1   0.002245       False      NaN
2   0.002244       False      NaN
3   0.002247        True     True
4   0.002249        True     True
5   0.002247        True     True
6   0.002250        True     True
7   0.002250        True     True
8   0.002250        True     True
9   0.002251       False      NaN
10  0.002251        True    False
11  0.002250        True    False

Upvotes: 2

Related Questions