我想我遗漏了一些关于交叉相关的基本信息。我有两个时间序列,x和y(Pandas系列,带日期时间索引,长度相等)。我想检查时间对齐-例如,确保两个时间序列中的上下位大致同时出现,如果它们不在同一时间,则将它们移动到对齐状态。为此,我使用scipy.signal.correlate来查找两个时间序列之间相关性最高的滞后。
def time_alignment_check(x, y):
from scipy import signal
x = x.dropna()
y = y.dropna()
corr = signal.correlate(x, y)
lags = signal.correlation_lags(len(x), len(y))
corr /= np.max(corr)
fig, (ax_data, ax_corr) = plt.subplots(2, 1, figsize=(7, 8))
ln1 = ax_data.plot(x, 'r', label='x')
ax2 = ax_data.twinx()
ln2 = ax2.plot(y, 'b', label='y')
ax_data.legend()
ax_data.set_xlabel('Time')
ax_data.xaxis.set_major_formatter(dates.DateFormatter('%H:%M:%S'))
lns = ln1 + ln2
labs = [l.get_label() for l in lns]
ax_data.legend(lns, labs, loc=0)
ax_corr.plot(lags, corr)
ax_corr.annotate(f'max. corr. where lag={lags[np.argmax(corr)]}',
xy=(0.35, 0.1), xycoords='axes fraction', fontsize=10, color='k',
bbox=dict(facecolor='white', alpha=0.8, ec='k'))
ax_corr.set_title('Cross-correlated signal')
ax_corr.set_xlabel('Lag')
ax_corr.set_xlim([-200, 200])
ax_data.margins(0, 0.1)
ax_corr.margins(0, 0.1)
fig.tight_layout()
plt.show()
对整个时间序列(图1)运行分析会产生26秒的滞后。因此,我将y向右移动26秒,然后重新运行分析。我希望滞后等于0,但它没有,它仍然等于26......为什么?当我对较小的数据块/样条运行分析时,例如,从13:00:00到13:40:00的40分钟数据块(图2),滞后=1秒。再次将较小数据块上的y移动n秒不会改变滞后。
Signal correlation shift and lag correct only if arrays subtracted by mean建议从数据集中扣除平均值,对于更短、变化更少的数据集(如下文所示),该平均值给出了正确的滞后。
y = pd.Series([1.,1.,1.,1.,2.,2.,1.,1.,1.,1.], index=range(0,10))
x = pd.Series([1.,1.,1.,1.,1.,1.,1.,2.,2.,1.], index=range(0,10))
x -= np.mean(x)
y -= np.mean(y)
这种方法(扣除平均值)也会对我的数据产生不正确的结果。这里我遗漏了什么?
提前感谢!
1条答案
按热度按时间wlsrxk511#
我明白了。对于Pandas系列的x和y,这与数据如何移动有关。如果使用freq='s'(秒)来应用移动(pd.shift),你会得到一个不正确的滞后,尽管(对我来说!)x和y的绘图将显示n秒的正确移动(这实际上是有意义的,一旦我正确阅读了文档:“如果指定了freq,则索引值会移动,但数据不会重新对齐”。)。当freq=None时,会显示正确的结果。