I think this should be relatively easy but I'm a noob!

Need to return results in a new pandas column (call this column B) that is based on the result of the below row in column A.

Please print the below code

import pandas as pd
df = pd.DataFrame({'A': ['BUY', 'BUY', 'HODL', 'SELL', 'HODL', 'HODL', 'BUY', 'SELL', 'SELL', 'BUY', 'BUY', 'HODL', 'SELL', 'SELL', 'SELL', 'HODL', 'SELL', 'SELL','BUY']})
print(df)

I need a new column (column B) to return results based on following.

Starting from the bottom of the pandas dataframe. The last cell in column A (ie A18 = 'BUY') can always return the same result for last cell in column B.

The next row up in column A (ie A17) is a 'SELL'. I regard this as a change and as such cell B17 should now also be a 'SELL'

The next row up in column A (ie A16) is a 'SELL' again. As this is no change from A17, cell B16 should now be a 'NA'

The next row up in column A (ie A15) is a 'HODL'. All 'HODL' cells should always be reflected as 'HODL' cells in column B

If cell A15 was however a 'SELL' again another 'NA' would be applied in column B.

The same princples for 'SELL' cells apply for 'BUY' cells

The following df has been provided only to provide a visualisation of the expected result:

import pandas as pd

df = pd.DataFrame({'A': ['BUY', 'BUY', 'HODL', 'SELL', 'HODL', 'HODL', 'BUY', 'SELL', 'SELL', 'BUY', 'BUY', 'HODL', 'SELL', 'SELL', 'SELL', 'HODL', 'SELL', 'SELL','BUY'], 'B': ['NA', 'BUY', 'HODL', 'SELL', 'HODL', 'HODL', 'BUY', 'NA', 'SELL', 'NA', 'BUY', 'HODL', 'NA', 'NA', 'SELL', 'HODL', 'NA', 'SELL','BUY']})

print(df)

1 Answers

1
Erfan On Best Solutions

numpy.select & Series.shift

We can use numpy.select for this so we can define multiple conditions and based on those conditions we can assign values to your new column B.

In our conditions we use Series.shift which we use so we can check if the next value is SELL or BUY.

Series.eq is the same as using == 'SELL' for example

Note I reverse your dataframe, since you want to apply the logic from the bottom up, I do this with df[::-1]. Which is the same method to reverse a list in Python.

# Reverse dataframe
df = df[::-1]

conditions = [
    df['A'].eq('HODL'),
    df['A'].eq('SELL') & df['A'].shift().eq('SELL'),
    df['A'].eq('BUY') & df['A'].shift().eq('BUY')
]

choices = ['HODL', 'NA', 'NA']

df['B'] = np.select(conditions, choices, default=df['A'])

# Reverse dataframe back to original state
df = df[::-1]

Output

print(df)
       A     B
0    BUY    NA
1    BUY   BUY
2   HODL  HODL
3   SELL  SELL
4   HODL  HODL
5   HODL  HODL
6    BUY   BUY
7   SELL    NA
8   SELL  SELL
9    BUY    NA
10   BUY   BUY
11  HODL  HODL
12  SELL    NA
13  SELL    NA
14  SELL  SELL
15  HODL  HODL
16  SELL    NA
17  SELL  SELL
18   BUY   BUY