How to have pandas perform a rolling average on a non-uniform x-grid
The key question remains: what do you want to achieve with the rolling mean ?
Mathematically a clean way is:
- interpolate to the finest dx of the x-data
- perform the rolling mean
- take out the data points you want (But be careful: this step is a type of averaging too!)
Here is the code for the interpolation:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
x_val = [1,2,4,8,16,32,64,128,256,512]
y_val = [x+np.random.random()*200 for x in x_val]
df = pd.DataFrame(data={'x':x_val,'y':y_val})
df.set_index('x', inplace=True)
#df.plot()
df.rolling(5, win_type='gaussian').mean(std=200).plot()
#---- Interpolation -----------------------------------
f1 = interp1d(x_val, y_val)
f2 = interp1d(x_val, y_val, kind='cubic')
dx = np.diff(x_val).min() # get the smallest dx in the x-data set
xnew = np.arange(x_val[0], x_val[-1]+dx, step=dx)
ynew1 = f1(xnew)
ynew2 = f2(xnew)
#---- plot ---------------------------------------------
fig = plt.figure(figsize=(15,5))
plt.plot(x_val, y_val, '-o', label='data', alpha=0.5)
plt.plot(xnew, ynew1, '|', ms = 15, c='r', label='linear', zorder=1)
#plt.plot(xnew, ynew2, label='cubic')
plt.savefig('curve.png')
plt.legend(loc='best')
plt.show()