I have two time series, and i suspect that there is a time shift between them, and i want to estimate this time shift.
This question has been asked before in: Find phase
Indeed, interesting problem, but no satisfying answer yet. Let's try to change that...
You say that you prefer not to use interpolation, but, as I understand from your comment, what you really mean is that you would like to avoid upsampling to a higher resolution. A basic solution makes use of a least squares fit with a linear interpolation function, but without upsampling to a higher resolution:
import numpy as np
from scipy.interpolate import interp1d
from scipy.optimize import leastsq
def yvals(x):
return np.sin(x)+np.sin(2*x)+np.sin(3*x)
dx = .1
X = np.arange(0,2*np.pi,dx)
Y = yvals(X)
unknown_shift = np.random.random() * dx
Y_shifted = yvals(X + unknown_shift)
def err_func(p):
return interp1d(X,Y)(X[1:-1]+p[0]) - Y_shifted[1:-1]
p0 = [0,] # Inital guess of no shift
found_shift = leastsq(err_func,p0)[0][0]
print "Unknown shift: ", unknown_shift
print "Found shift: ", found_shift
A sample run gives a quite accurate solution:
Unknown shift: 0.0695701123582
Found shift: 0.0696105501967
If one includes noise in the shifted Y:
Y_shifted += .1*np.random.normal(size=X.shape)
One gets somewhat less precise results:
Unknown shift: 0.0695701123582
Found shift: 0.0746643381744
The accuracy under presence of noise improves when more data is available, e.g. with:
X = np.arange(0,200*np.pi,dx)
A typical result is:
Unknown shift: 0.0695701123582
Found shift: 0.0698527939193