Home > front end >  Python & Pandas: apply scoring function to df new column not working
Python & Pandas: apply scoring function to df new column not working

Time:05-13

I want to create a score based on the value of several columns in the dataframe. I created the following snippet but the function does not apply as it return only 0 values...

def momentum_score (row): 
   
    if ((row['rsi_1'] < 30) & (row['rsi_2'] > 30) & (row['rsi_3'] > 30)):
        val = 1  
    if ((row['rsi_1'] < 30) & (row['rsi_2'] < 30) & (row['rsi_3'] > 30)):
        val = 2 
    if ((row['rsi_1'] < 30) & (row['rsi_2'] < 30) & (row['rsi_3'] < 30)):
        val = 3
    else:
        val=0
    return val
    
dfw['mom'] = dfw.apply(momentum_score, axis=1)
dfw

Please see the picture to have a look at my dataframe enter image description here

CodePudding user response:

You can try with apply but it's slower than a vectorized solution. The problem is the use of the if-elif-els statement.

def momentum_score (row): 
    if ((row['rsi_1'] < 30) & (row['rsi_2'] > 30) & (row['rsi_3'] > 30)):
        val = 1  
    elif ((row['rsi_1'] < 30) & (row['rsi_2'] < 30) & (row['rsi_3'] > 30)):
        val = 2 
    elif ((row['rsi_1'] < 30) & (row['rsi_2'] < 30) & (row['rsi_3'] < 30)):
        val = 3
    else:
        val=0
    return val
    
dfw['mom'] = dfw.apply(momentum_score, axis=1)
dfw

CodePudding user response:

Use np.select

rsi1 = dfw['rsi_1']
rsi2 = dfw['rsi_2']
rsi3 = dfw['rsi_3']

conds =\
[(rsi1 < 30) & (rsi2 > 30) & (rsi3 > 30), 
 (rsi1 < 30) & (rsi2 < 30) & (rsi3 > 30),
 (rsi1 < 30) & (rsi2 < 30) & (rsi3 < 30)]
choices = [1, 2, 3]
#choices = list(range(1, len(conds) 1))

df['mom'] = np.select(conds, choices, default=0)

CodePudding user response:

Try the following instead (untested, but I think this is what you want):

dfw.loc['mom'] = 0  # default value

rsi1 = dfw['rsi_1']
rsi2 = dfw['rsi_2']
rsi3 = dfw['rsi_3']
dfw.loc[(rsi1 < 30) & (rsi2 > 30) & (rsi3 > 30), 'mom'] = 1
dfw.loc[(rsi1 < 30) & (rsi2 < 30) & (rsi3 > 30), 'mom'] = 2
dfw.loc[(rsi1 < 30) & (rsi2 < 30) & (rsi3 < 30), 'mom'] = 3
  • Related