Simple moving averages, or SMAs, show the average value for a numeric value over a specific number of previous periods and are very useful in time series analysis, both as model features and for interpreting patterns in the data. They’re very easy to calculate using the Pandas `rolling()`

function.

Exponential moving averages (EMAs) or exponentially weighted moving averages (EWMAs), are similar but differ in assigning a greater weight to the most recent observations, allowing them to identify recent trends better than regular moving averages. EMAs are commonly used in financial forecasting as a result.

In this simple tutorial I’ll show you how you can use the Pandas `ewm()`

method to calculate an exponential moving average of the values in a Pandas column for a number of different periods.

To get started, open a Jupyter notebook and import the Pandas library using the `import pandas as pd`

naming convention, then import a time series dataset into a Pandas dataframe. This needs to be sorted by date and include a numeric column upon which you can calculate your exponential moving average.

```
import pandas as pd
```

```
df = pd.read_csv('https://raw.githubusercontent.com/flyandlure/datasets/master/ecommerce_sales_by_date.csv',
usecols=['date', 'transactions'],
parse_dates=['date'])
df.head(10)
```

date | transactions | |
---|---|---|

0 | 2021-01-01 | 125 |

1 | 2021-01-02 | 161 |

2 | 2021-01-03 | 157 |

3 | 2021-01-04 | 99 |

4 | 2021-01-05 | 91 |

5 | 2021-01-06 | 99 |

6 | 2021-01-07 | 87 |

7 | 2021-01-08 | 112 |

8 | 2021-01-09 | 161 |

9 | 2021-01-10 | 164 |

First, we’ll calculate a simple moving average, so you can compare how the result differs from an exponentially weighted moving average. We’ll do this using the Pandas `rolling()`

function.

We’ll append a call to `assign()`

to our dataframe and tell it to create a new column called `sma_3day`

and assign to it the result of `rolling(3).mean()`

to give us the three-day simple moving average for each column value. Note that `rolling()`

will give us `NaN`

values when there aren’t enough prior values to use for the calculation.

```
df = df.assign(sma_3day = df['transactions'].rolling(3).mean())
df.head()
```

date | transactions | sma_3day | |
---|---|---|---|

0 | 2021-01-01 | 125 | NaN |

1 | 2021-01-02 | 161 | NaN |

2 | 2021-01-03 | 157 | 147.666667 |

3 | 2021-01-04 | 99 | 139.000000 |

4 | 2021-01-05 | 91 | 115.666667 |

Next, we’ll calculate the EMA using the `ewm()`

function. There are various parameters you can pass to the Pandas `ewm()`

function to adjust how Pandas calculates an exponential moving average. The most important of these is the `span`

parameter which takes an integer value define the number of rows to compare.

For example, `df['transactions'].ewm(span=3, adjust=False).mean()`

will calculate the exponential moving average for the `transactions`

column over three previous rows. If there are no previous rows, Pandas will calculate based on the values that are available.

We can use the Pandas `assign()`

method to calculate the exponentially weighted moving average for several periods simply by providing a different value to the `span`

parameter and assigning the values back to the new column name and saving the final dataframe.

```
df = df.assign(
ewm_3day = df['transactions'].ewm(span=3, adjust=False).mean(),
ewm_7day = df['transactions'].ewm(span=7, adjust=False).mean(),
ewm_10day = df['transactions'].ewm(span=7, adjust=False).mean(),
)
df.head(10)
```

date | transactions | sma_3day | ewm_3day | ewm_7day | ewm_10day | |
---|---|---|---|---|---|---|

0 | 2021-01-01 | 125 | NaN | 125.000000 | 125.000000 | 125.000000 |

1 | 2021-01-02 | 161 | NaN | 143.000000 | 134.000000 | 134.000000 |

2 | 2021-01-03 | 157 | 147.666667 | 150.000000 | 139.750000 | 139.750000 |

3 | 2021-01-04 | 99 | 139.000000 | 124.500000 | 129.562500 | 129.562500 |

4 | 2021-01-05 | 91 | 115.666667 | 107.750000 | 119.921875 | 119.921875 |

5 | 2021-01-06 | 99 | 96.333333 | 103.375000 | 114.691406 | 114.691406 |

6 | 2021-01-07 | 87 | 92.333333 | 95.187500 | 107.768555 | 107.768555 |

7 | 2021-01-08 | 112 | 99.333333 | 103.593750 | 108.826416 | 108.826416 |

8 | 2021-01-09 | 161 | 120.000000 | 132.296875 | 121.869812 | 121.869812 |

9 | 2021-01-10 | 164 | 145.666667 | 148.148438 | 132.402359 | 132.402359 |

Matt Clarke, Monday, January 09, 2023