tarot tarot - 9 days ago 6
Python Question

Adding a column (EMA) thats result of previous new column value in pandas

My Orignal dataframe is like:

Date C
0 a
1 b
2 c
3 d


This is a Stock data.
0,1,2,3 are times, C:Close are float.

I need to be able to add a column that's EMA(Exponential Moving average) to the orignal dataframe which is got by computing from current Column C
and the previous new column ('EMA').

Calculation example on Excel

Cr:http://investexcel.net/how-to-calculate-ema-in-excel/

So the result should be like this

C EMA
0 a start value as ema0
1 b (ema0*alpha) + (b * (1-alpha)) as ema1
2 c (ema1*alpha) + (c * (1-alpha)) as ema2
3 d (ema2*alpha) + (d * (1-alpha)) as ema3
4 e (ema3*alpha) + (e * (1-alpha)) as ema4
... ... ....


The starting value would be a simple Average value so I've tried the following method .
It's work for the first condition to create starting value
but it's not working for the second condition when calculating EMA value.

ema_period = 30
myalpha = 2/(ema_period+1)

data['EMA'] = np.where(data['index'] < ema_period,data['C'].rolling(window=ema_period, min_periods=ema_period).mean(), data['C']*myalpha +data['EMA'].shift(1)*(1-myalpha) )

Answer

Required EWMA from your enclosed image:

enter image description here

Code:

ema_period = 12             # change it to ema_period = 30 for your case
myalpha = 2/(ema_period+1)

# concise form : df.expanding(min_periods=12).mean()
df['Expand_Mean'] = df.rolling(window=len(df), min_periods=ema_period).mean()
# obtain the very first index after nulls
idx = df['Expand_Mean'].first_valid_index()
# Make all the subsequent values after this index equal to NaN
df.loc[idx:, 'Expand_Mean'].iloc[1:] = np.NaN
# Let these rows now take the corresponding values in the Close column
df.loc[idx:, 'Expand_Mean'] = df['Expand_Mean'].combine_first(df['Close'])
# Perform EMA by turning off adjustment
df['12 Day EMA'] = df['Expand_Mean'].ewm(alpha=myalpha, adjust=False).mean()
df

Obtained EWMA:

enter image description here


DF construction:

index = ['1/2/2013','1/3/2013','1/4/2013','1/7/2013','1/8/2013','1/9/2013', '1/10/2013','1/11/2013',
         '1/14/2013','1/15/2013','1/16/2013','1/17/2013','1/18/2013','1/22/2013','1/23/2013',
         '1/24/2013','1/25/2013','1/28/2013','1/29/2013','1/30/2013']
data = [42.42, 43.27, 43.66, 43.4, 43.4, 44.27, 45.01, 44.48, 44.34, 
        44.44, 44.08, 44.16, 44.04, 43.74, 44.27, 44.11, 43.93, 44.35,
        45.21,44.92]

df = pd.DataFrame(dict(Close=data), index)
df.index = pd.to_datetime(df.index)
Comments