numpy.correlate 不将数据居中,所以在调用方法之前应该这样做:
corr = np.correlate(data_1 - np.mean(data_1),
data_2 - np.mean(data_2),
mode='full')
这只会将corr 改变一个常数,但仍然是合理的做法:不相关的变化将显示为 0。
其次,您的图表在一个水平刻度上包含所有三件事似乎没有帮助;使用mode='full',相关数组的长度大约是原始数组长度的两倍。
选择corr 和corr.argmax() 的最大值是合理的做法。只需了解索引在此处的工作方式即可。使用 mode='full' 时,corr 的第 0 个索引对应于 formula sum_n a[n+k] * conj(v[n]) 中 1 - len(a) 中的移位 k,这意味着 a 向左移动了极远,因此只有一个重叠元素在 a 和 v 之间移动。因此,从该索引中减去len(a) - 1 会得到a 相对于v 的实际偏移。
虚构的例子:
import numpy as np
import matplotlib.pyplot as plt
data_1 = np.sin(np.linspace(0, 10, 100))
data_1 += np.random.uniform(size=data_1.shape) # noise
data_2 = np.cos(np.linspace(0, 7, 70))
data_2 += np.random.uniform(size=data_2.shape) # noise
corr = np.correlate(data_1 - np.mean(data_1),
data_2 - np.mean(data_2),
mode='full')
plt.plot(corr)
plt.show()
lag = corr.argmax() - (len(data_1) - 1)
print(lag)
plt.plot(data_1, 'r*')
plt.plot(data_2, 'b*')
plt.show()
这里的滞后被打印为 -14 或 -15(取决于随机噪声),在此比例上表示 -1.4 或 -1.5。这是合理的,因为 sin 比 cos 低 pi/2,即大约 1.57。换句话说,将红点向左移动 14-15 个元素可以最大化与蓝点的匹配。
数据:
相关性: