Smoothing with moving average

import pandas as pd import matplotlib.pyplot as plt import numpy as np def non_nan(vals): return np.ma.masked_where(np.isnan(vals), vals) fig, ax = plt.subplots(figsize=(7.4, 4.5)) ax.set_title('Smoothing with moving average') np.random.seed(0) window_size = 5 half_size = window_size // 2 mid = half_size + 1 side = [np.nan]*half_size d = np.random.randint(-100, 100, 100).tolist() data = side + d + side data1, data2 = [np.nan]*len(data), [np.nan]*len(data) for i in range(window_size, len(data) - 1): data1[i-half_size] = sum(data[i-window_size:i]) / window_size for i in range(window_size, len(data) - 1): data2[i-half_size] = sum(data1[i-window_size:i]) / window_size smoothed = pd.Series(d).rolling(window_size, center=True).mean().tolist() data1_slice = data1[half_size+1:-half_size+1] print(np.all(non_nan(smoothed) == non_nan(data1_slice))) # True plt.plot(data, 'k-', label='original data', alpha=0.4) plt.plot(data1, 'r-', label='moving average applied once', alpha=0.6) plt.plot(data2, 'b-', label='moving average applied twice', alpha=1) leg = plt.legend(loc='best', frameon=False) for l in leg.get_lines(): l.set_linewidth(4) plt.tight_layout() plt.show() A sequence of points where extreme values are smoothed by moving average