如何使用互相关找到两个时间序列之间的滞后

How to find the lag between two time series using cross-correlation

假设这两个系列是:

x = [4,4,4,4,6,8,10,8,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4]
y = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,8,10,8,6,4,4]

系列 x 明显滞后于 y 12 个时间段。 但是,使用 Python cross correlation 中建议的以下代码:

import numpy as np
c = np.correlate(x, y, "full")
lag = np.argmax(c) - c.size/2

导致 -0.5 的错误滞后。
这里有什么问题?

如果你想以简单的方式做到这一点,你应该简单地使用 scipy correlation_lags

此外,请记住从输入中减去平均值。

import numpy as np
from scipy import signal
x = [4,4,4,4,6,8,10,8,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4]
y = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,8,10,8,6,4,4]
correlation = signal.correlate(x-np.mean(x), y - np.mean(y), mode="full")
lags = signal.correlation_lags(len(x), len(y), mode="full")
lag = lags[np.argmax(abs(correlation))]

这给出 lag=-12,即 xy 中前六个索引之间的差异,如果交换输入,它给出 +12

编辑

为什么要减去均值

如果信号具有非零值,则相关性中心的项将变得更大,因为那里有更大的支持样本来计算相关性。此外,对于非常大的数据,减去平均值可以使计算更准确。

这里我举例说明如果不减去平均值会发生什么。

plt.plot(abs(correlation))
plt.plot(abs(signal.correlate(x, y, mode="full")))
plt.plot(abs(signal.correlate(np.ones_like(x)*np.mean(x), np.ones_like(y)*np.mean(y))))
plt.legend(['subtracting mean', 'constant signal', 'keeping the mean'])

请注意蓝色曲线上的最大值(10)与橙色曲线上的最大值不重合。