Python 估计两个时间序列之间的小时间偏移
我有两个时间序列,我怀疑它们之间有时间偏移,我想估计这个时间偏移 这一问题以前曾在: 但在我的例子中,时间偏移小于数据的分辨率。例如,数据以每小时一次的分辨率提供,时间偏移仅为几分钟(见图) 这是因为用于测量其中一个系列的数据记录器的时间偏移了几分钟 有没有算法可以估计这种偏移,最好不用插值Python 估计两个时间序列之间的小时间偏移,python,statistics,scipy,signal-processing,correlation,Python,Statistics,Scipy,Signal Processing,Correlation,我有两个时间序列,我怀疑它们之间有时间偏移,我想估计这个时间偏移 这一问题以前曾在: 但在我的例子中,时间偏移小于数据的分辨率。例如,数据以每小时一次的分辨率提供,时间偏移仅为几分钟(见图) 这是因为用于测量其中一个系列的数据记录器的时间偏移了几分钟 有没有算法可以估计这种偏移,最好不用插值 这是一个非常有趣的问题。这里有一个使用傅里叶变换的部分解的尝试。这取决于数据具有适度的周期性。我不确定它是否适用于您的数据(端点的导数似乎不匹配) 将numpy导入为np X=np.linspace(0,2
这是一个非常有趣的问题。这里有一个使用傅里叶变换的部分解的尝试。这取决于数据具有适度的周期性。我不确定它是否适用于您的数据(端点的导数似乎不匹配)
将numpy导入为np
X=np.linspace(0,2*np.pi,30)#一些X值
def yvals(x):
返回np.sin(x)+np.sin(2*x)+np.sin(3*x)
Y1=yvals(X)
Y2=yvals(X-0.1)#移动的y值
#傅里叶变换两个级数
FT1=np.fft.fft(Y1)
FT2=np.fft.fft(Y2)
#从分析上可以看出,系数中的相移会导致
#`exp(-1.j*N*T\d)的乘法因子`
#无法接受第0个元素,因为这是0的除法。分析而言,
#根据L'hopital的规则,除以0是可以的,但计算机不懂微积分:)
打印np.log(FT2[1://FT1[1:])/(-1.j*np.arange(1,len(X)))
对打印输出的快速检查表明,频率最高
幂(N=1,N=2)给出了合理的估计,如果你看一下
绝对值(np.absolute),尽管我无法解释为什么会这样
也许更熟悉数学的人可以从这里得到更好的答案…您提供的一个链接有正确的想法(事实上,我在这里做的事情几乎相同) 它具有以下输出:
Preset shift: -3
Calculated shift: -2.99
可能需要检查一下
请注意,相关性的argmax()表示对齐的位置,必须按b-a=10-0=10
和N的长度进行缩放,以获得实际值
检查correlate的源并不完全清楚从sigtools导入的函数的行为。对于大型数据集,循环相关(通过快速傅立叶变换)比直接方法快得多。我怀疑这就是sigtools中实现的东西,但我不能确定。在我的python2.7文件夹中搜索该文件时,只返回已编译的C pyd文件。我已成功使用(在awgn通道中)匹配过滤器方法,该方法在索引n处给出峰值能量m[n];然后将二次多项式f(n)拟合到m[n-1],m[n],m[n+1],并通过设置f'(n)==0来找到最小值
响应不一定是绝对线性的,特别是当信号的自相关在m[n-1],m[n+1]处不消失时。这是一个非常有趣的问题。最初,我打算提出一个类似于user948652的基于互相关的解决方案。但是,根据您的问题描述,该解决方案存在两个问题:
Unknown shift: 0.0695701123582
Found shift: 0.0696105501967
width=1
sunrise_index = get_sunrise()
sunset_index = get_sunset()
# set the data to zero, except for the sunrise/sunset events.
bitmap = zeros(data.shape)
bitmap[sunrise_index - width : sunrise_index + width] = 1
bitmap[sunset_index - width : sunset_index + width] = 1
sunrise_sunset = data * bitmap
有几种方法可以实现获取日出()
和获取日落()。我会使用,在一个特定的值上设置阈值,然后取高于该值的第一个和最后一个点。您还可以从大量文件中读取夜间数据,计算平均值和标准偏差,并查找超过夜间数据的第一个和最后一个数据点,例如,0.5*st_dev
。您还可以执行某种基于群集的模板匹配,特别是在不同类别的白天(即晴天、部分多云和非常多云)具有高度定型的日出/日落事件时
2。重新采样数据
我不认为没有插值就没有办法解决这个问题。我会使用重采样的数据,以更高的采样率比转移。如果班次以分钟为单位,则将采样增加到1分钟或30秒
num_samples = new_sample_rate * sunrise_sunset.shape[0]
sunrise_sunset = scipy.signal.resample(sunrise_sunset, num_samples)
或者,我们可以使用三次样条插值数据(请参见)
3。高斯卷积
因为有一些插值,所以我们不知道实际的日出和日落是如何精确预测的。所以,我们可以用高斯函数来卷积信号,来表示这种不确定性
gaussian_window = scipy.signal.gaussian(M, std)
sunrise_sunset_g = scipy.signal.convolve(sunrise_sunset, gaussian_window)
4。互相关
使用互相关法
gaussian_window = scipy.signal.gaussian(M, std)
sunrise_sunset_g = scipy.signal.convolve(sunrise_sunset, gaussian_window)
np.sqrt((X1-X2+delta_x)**2+(Y1-Y2)**2).sum()
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)
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
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
Unknown shift: 0.0695701123582
Found shift: 0.0696105501967
Y_shifted += .1*np.random.normal(size=X.shape)
Unknown shift: 0.0695701123582
Found shift: 0.0746643381744
X = np.arange(0,200*np.pi,dx)
Unknown shift: 0.0695701123582
Found shift: 0.0698527939193