如何关联有间隙和不同时间基准的两个时间序列?

14 投票
5 回答
8570 浏览
提问于 2025-04-16 12:36

我有两组3D加速度计的数据,它们的时间基准不同(也就是说,它们的时钟是不同时间开始的,采样期间也有一些微小的偏差),而且数据中有很多不同大小的空缺(这是因为写入不同的闪存设备时会有延迟)。

我使用的加速度计是便宜的 GCDC X250-2。我把加速度计调到最高增益,所以数据中有很多噪声。

每组时间序列大约有200万个数据点(在一个小时内以每秒512个样本的速度采样),并且包含大约500个感兴趣的事件,通常每个事件跨越100到150个样本(每个事件大约200到300毫秒)。这些事件中的许多都受到闪存写入时数据中断的影响。

所以,这些数据并不完美,甚至看起来也不太好。但我用眼睛检查后发现,它们明显包含了我感兴趣的信息。(如果需要,我可以发布一些图表。)

这两个加速度计处于相似的环境中,但它们的耦合程度一般,这意味着我可以通过眼睛判断出哪个事件是来自每个加速度计的,但到目前为止我在软件上还没有成功。由于物理限制,这些设备的安装方向也不同,轴线不匹配,但我尽量让它们接近正交。例如,对于3轴加速度计A和B,+Ax对应-By(上下),+Az对应-Bx(左右),+Ay对应-Bz(前后)。

我最初的目标是关联垂直轴上的冲击事件,尽管我最终想要a) 自动发现轴的映射,b) 关联映射后的活动,c) 提取两个加速度计之间的行为差异(比如扭转或弯曲)。

由于时间序列数据的特性,Python的numpy.correlate()无法使用。我也看过R的Zoo包,但没有取得进展。我还查看了信号分析的不同领域寻求帮助,但也没有什么进展。

有没有人能给我一些线索,或者我应该研究哪些方法?

更新于2011年2月28日:添加了一些图表 在这里,展示了数据的示例。

5 个回答

1

这不是一个技术性的答案,但可能会帮助你想出一个解决办法:

  • 把图表转换成图片,然后放到像gimp或photoshop这样的好图像处理软件里。
  • 每当有空隙时,把图表分成独立的图片。
  • 把第一组图表排成一行。
  • 把第二组图表放在第一组正下方,排成一行。
  • 找出第一个相关的事件。
  • 如果这两个事件没有垂直对齐:
    • 选择左边更靠近的那个事件,以及这一行右边的所有内容。
    • 把这些内容拖到右边,直到它们对齐。

这其实和音频编辑器的工作原理差不多,所以如果你把它转换成简单的音频格式,比如无压缩的WAV文件,你就可以在像Audacity这样的软件里直接操作它。(当然,听起来会很糟糕,但你可以很容易地移动数据图表。)

实际上,Audacity还有一种叫做nyquist的脚本语言,所以如果你不需要程序去检测这些相关性(或者你至少愿意暂时跳过这一步),你可以用Audacity的标记和nyquist的组合来自动对齐,并在标记相关点后导出你想要的干净数据格式。

1

如果数据中有一些未知大小的空缺,而且每个时间序列的空缺大小都不一样,那么我就不再尝试对整个序列进行关联了。相反,我会尝试对每个时间序列中的一对短窗口进行交叉关联,比如说使用长度是典型事件的两倍(300个样本长)的重叠窗口。这样可以在所有可能的组合中找到潜在的高交叉相关匹配,然后对这些潜在匹配施加一个顺序约束,以便得到匹配窗口的序列。

这样一来,你就会得到一些更小的问题,这些问题更容易分析。

4

我理解你的问题是:给定两个非常长且嘈杂的时间序列,找出一个序列的位移,使得一个信号中的大“波峰”能够与另一个信号中的大波峰对齐。

我的建议是:先对数据进行插值处理,使得数据间隔均匀,然后对数据进行修正和平滑(假设快速波动的相位不重要),接着进行逐点的交叉相关分析(假设小的位移可以使数据对齐)。

import numpy
from scipy.ndimage import gaussian_filter
"""
sig1 and sig 2 are assumed to be large, 1D numpy arrays
sig1 is sampled at times t1, sig2 is sampled at times t2
t_start, t_end, is your desired sampling interval
t_len is your desired number of measurements
"""

t = numpy.linspace(t_start, t_end, t_len)
sig1 = numpy.interp(t, t1, sig1)
sig2 = numpy.interp(t, t2, sig2)
#Now sig1 and sig2 are sampled at the same points.

"""
Rectify and smooth, so 'peaks' will stand out.
This makes big assumptions about your data;
these assumptions seem true-ish based on your plots.
"""
sigma = 10 #Tune this parameter to get the right smoothing
sig1, sig2 = abs(sig1), abs(sig2)
sig1, sig2 = gaussian_filter(sig1, sigma), gaussian_filter(sig2, sigma)

"""
Now sig1 and sig2 should look smoothly varying, with humps at each 'event'.
Hopefully we can search a small range of shifts to find the maximum of the 
cross-correlation. This assumes your data are *nearly* lined up already.
"""
max_xc = 0
best_shift = 0
for shift in range(-10, 10): #Tune this search range
    xc = (numpy.roll(sig1, shift) * sig2).sum()
    if xc > max_xc:
        max_xc = xc
        best_shift = shift
print 'Best shift:', best_shift
"""
If best_shift is at the edges of your search range,
you should expand the search range.
"""

撰写回答