Estimating small time shift between two time series

后端 未结 6 1937
野性不改
野性不改 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:54

    Optimize for the best solution

    For the constraints given, namely that the solution is phase-shifted by a small amount less than the sampling method, a simple downhill simplex algorithm works well. I've modified the sample problem of @mgilson to show how to do this. Note that this solution is robust, in that it can handle noise.

    Error function: There may be more optimal things to optimize over, but this works surprisingly well:

    np.sqrt((X1-X2+delta_x)**2+(Y1-Y2)**2).sum()
    

    That is, minimize the Euclidean distance between the two curves by only adjusting the x-axis (phase).

    import numpy as np
    
    def yvals(x):
        return np.sin(x)+np.sin(2*x)+np.sin(3*x)
    
    dx = .1
    unknown_shift = .03 * np.random.random() * dx
    
    X1  = np.arange(0,2*np.pi,dx)  #some X values
    X2  = X1 + unknown_shift
    
    Y1 = yvals(X1)
    Y2 = yvals(X2) # shifted Y
    Y2 += .1*np.random.normal(size=X1.shape)  # now with noise
    
    def err_func(p):
        return np.sqrt((X1-X2+p[0])**2+(Y1-Y2)**2).sum()
    
    from scipy.optimize import fmin
    
    p0 = [0,] # Inital guess of no shift
    found_shift = fmin(err_func, p0)[0]
    
    print "Unknown shift: ", unknown_shift
    print "Found   shift: ", found_shift
    print "Percent error: ", abs((unknown_shift-found_shift)/unknown_shift)
    

    A sample run gives:

    Optimization terminated successfully.
             Current function value: 4.804268
             Iterations: 6
             Function evaluations: 12
    Unknown shift:  0.00134765446268
    Found   shift:  0.001375
    Percent error:  -0.0202912082305
    

提交回复
热议问题