Estimating small time shift between two time series

后端 未结 6 1905
野性不改
野性不改 2021-01-30 23:04

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

6条回答
  •  面向向阳花
    2021-01-30 23:55

    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
    

提交回复
热议问题