Gabriel
Gabriel

Reputation: 3807

Ewma in pandas but over rolling weekly data.

I'm trying to calculate the ewma in pandas on a "rolling weekly" way. For example lets say today is tuesday. Then today´s ewma would be calculated using only tuesdays data. (This tuesday, the previous tuesday, the one before and so on). Now tomorrow we would have to do the same thing but with wednesdays and so forth and so on. After doing this if i want to get a "rolling weekly ewma" that includes every day of the week, I need to combine each vector that was generated. Meaning the weekly ewma of only mondays, the weekly ewma of only tuesdays, the weekly ewma of only wednesdays, then thursdays and then fridays.
Now this combined vector (of each day) is the "rolling weekly ewma" I'm talking about.

Doesn't pandas have an embedded way of doing this? Currently this is how I do it:

import pandas as pd
import numpy as np

df  = pd.DataFrame(np.random.randn(1000,1),index=pd.date_range(pd.datetime(1995,3,30), freq='B', periods=1000),columns =['PX_LAST'] )

lista1 = ['mon','tue','wed','thu','fri']
lista4 = ['W-MON','W-TUE','W-WED','W-THU','W-FRI']

for x,y in zip(lista1,lista4):
    r = "{0} = pd.ewma(df.PX_LAST.resample('{1}'),span = 10)".format(x,y)
    exec r   

comb2 = mon.combine_first(tue)
for y in lista1[1:6]:
    w  = "comb2 =comb2.combine_first({0})".format(y)
    exec w
df['emaw'] = comb2

Upvotes: 0

Views: 1056

Answers (1)

Randy
Randy

Reputation: 14847

There's probably multiple ways to do this, but the way I'd do it is with a reduce.

Your resampled EWMA calls can be done with this list comprehension to give a list of DataFrames:

ewmas = [pd.ewma(df[['PX_LAST']].resample(w), span=10) for w in lista4]

and then we want to mash them all together, so we can do:

ewma_frame = reduce(pd.DataFrame.combine_first, ewmas)

and lastly join them back to the original frame with:

df.merge(ewma_frame, left_index=True, right_index=True)

As just a one-liner, it's:

df.merge(reduce(pd.DataFrame.combine_first, [pd.ewma(df[['PX_LAST']].resample(w), span=10) for w in lista4]), left_index=True, right_index=True)

which, if you run it after your code, appears to give the same value as your original method (with a different column heading that you can just rename).

Upvotes: 1

Related Questions