1

I'd like to calculate an exponential moving average in a Pandas Dataframe, but instead of the decay (or span, alpha, periods, etc...) being a float, I need it to be based on the value of another column.

Expectedly, the following code returns an error:

df['cost_EMA'] = df['cost'].ewm(span=df['ema_spans']).mean()
Marotte
  • 11
  • 2
  • The formula is based on a scalar, right? So I don't know if that has any mathematical meaning to give it an array of values. Presumably that array has different values? If it's all the same value then you just need to convert to a scaler, e.g. `df.ema_spans[0]`. But if not then I think this is more of a math problem than programming problem and I have no idea if there is an answer. – JohnE Jun 03 '20 at 01:28

1 Answers1

0

Here's an answer to my own question. Unfortunately, it's not vectorized, but uses the .apply() function

The idea is to define a function to calculate an array of weights for the Exponential Moving Average, then apply it as a dot prodcut:

def changing_weights(costs, **other_params):
  // Calculate alpha, span, whatever
  // Then an array of weights
  weights = weights / np.sum(weights)
  return weights

df['Changing EMA'] = df.rolling(ema_window).apply(lambda costs: np.dot(costs, changing_weights(costs,weighting_params)), raw=True)
Marotte
  • 11
  • 2
  • You will achieve the same result faster by using https://stackoverflow.com/a/33314347/1577683 . – jarm Mar 29 '21 at 18:53