pandasdataframelistrecord

How to calculate Relative Strength Index (RSI) and Exponential Moving Average (EMA) from a list in pandas


I have created a pandas dataframe (called df) as follows:

import pandas as pd
import numpy as np

ds = {'col1' : [[10,23,45],[54,67,65],[76,43,21]]}

df = pd.DataFrame(data=ds)

The dataframe looks like this:

print(df)

           col1
0  [10, 23, 45]
1  [54, 67, 65]
2  [76, 43, 21]

I need to create two new columns:


Solution

  • One possible way to do this is to define two functions. One for computing the RSI and one to calculate the EMA (note that in this one I chose the preiod 2, as you required, but it can be changed if needed).

    A word of advice. In the future, do put a little bit of context and possibly explanations of what you are aiming for. That will increase your chances for a reply. Not everybody is used to stock markets.

    Given you data, this would be:

    import pandas as pd
    import numpy as np
    
    ds = {'col1': [[10, 23, 45], [54, 67, 65], [76, 43, 21]]}
    df = pd.DataFrame(data=ds)
    
    def calculate_rsi(values):
        gains = []
        losses = []
        for i in range(1, len(values)):
            difference = values[i] - values[i-1]
            if difference > 0:
                gains.append(difference)
            else:
                losses.append(abs(difference))
        
        average_gain = np.mean(gains) if gains else 0
        average_loss = np.mean(losses) if losses else 0
        
        if average_loss == 0:  
            return 100
        else:
            rs = average_gain / average_loss
            rsi = 100 - (100 / (1 + rs))
            return rsi
    
    def calculate_ema(values, periods=2):
        weights = np.exp(np.linspace(-1., 0., periods))
        weights /= weights.sum()
        ema = np.convolve(values, weights, mode='full')[:len(values)]
        ema[:periods] = ema[periods]  
        return ema[-1]
    
    df['RSI_2'] = df['col1'].apply(calculate_rsi)
    df['EMA_2'] = df['col1'].apply(lambda x: calculate_ema(x, 2))
    
    print(df)
    
    

    Which retunrs:

               col1       RSI_2      EMA_2
    0  [10, 23, 45]  100.000000  28.916711
    1  [54, 67, 65]   86.666667  66.462117
    2  [76, 43, 21]    0.000000  37.083289