python中自相关函数的快速降噪方法?
我可以使用numpy的内置功能计算自相关:python中自相关函数的快速降噪方法?,python,numpy,scipy,correlation,Python,Numpy,Scipy,Correlation,我可以使用numpy的内置功能计算自相关: numpy.correlate(x,x,mode='same') 然而,由此产生的相关性自然是有噪声的。我可以对数据进行分区,计算每个结果窗口上的相关性,然后对它们进行平均,以计算更清晰的自相关性,类似于signal.welch所做的。在numpy或scipy中是否有一个方便的函数可以做到这一点,可能比我自己计算分区并循环数据更快 更新 这是由@kazemakase答案引起的。我试图用一些代码来说明我的意思,这些代码用于生成下图 可以看出,@kazem
numpy.correlate(x,x,mode='same')
然而,由此产生的相关性自然是有噪声的。我可以对数据进行分区,计算每个结果窗口上的相关性,然后对它们进行平均,以计算更清晰的自相关性,类似于signal.welch
所做的。在numpy
或scipy
中是否有一个方便的函数可以做到这一点,可能比我自己计算分区并循环数据更快
更新
这是由@kazemakase答案引起的。我试图用一些代码来说明我的意思,这些代码用于生成下图
可以看出,@kazemakase是正确的,AC函数自然地将噪声平均化。然而,AC的平均值具有更快的优势<代码>np。如果通过FFT使用循环卷积计算相关性,则相关性似乎按缓慢的O(n^2)
进行缩放,而不是我预期的O(nlogn)
TL-DR:要减少自相关函数中的噪声,请增加信号x的长度
在谱估计中,对数据进行分区和平均是一个有趣的想法。我希望它能起作用 自相关定义为 假设我们将数据划分为两个窗口。它们的自相关性变得 请注意,它们只是在计算范围上有所不同。基本上,我们将自相关的总和分为两部分。当我们把这些加在一起时,我们回到了原始的自相关!所以我们没有得到任何东西 结论是,在numpy/scipy中没有实现这样的东西,因为这样做没有意义 备注:
Rxx/n==(Rxx1*2/n+Rxx2*2/n)/2
。即,归一化部分自相关的平均值等于完全归一化自相关import matplotlib.pyplot as plt
import numpy as np
for n in [2**6, 2**8, 2**12]:
x = np.random.randn(n)
rx = np.correlate(x, x, mode='same') / n # ACF
l1 = np.arange(-n//2, n//2) # Lags
plt.plot(l1, rx, label='n={}'.format(n))
plt.legend()
plt.xlim(-20, 20)
plt.show()
@CrazyIvan抱歉,我编辑了我的答案-我确实使用了
相同的
选项。你可能会在这个帖子中找到一些帮助:谢谢你的回复,我编辑了我的答案,我仍然在测试一些东西,但你的分析当然是正确的。我无法反驳数学,现在回想起来似乎很明显,所以谢谢你!我确实发现,np.correlate
在大型数据集上的速度非常慢,分区允许更快的计算。不确定你是否找到了相同的答案?@Jack看起来像,所以你的O(n^2)断言似乎是正确的。如果您有大型阵列,请查看哪个阵列具有基于FFT的实现。
import matplotlib.pyplot as plt
import numpy as np
n = 2**16
n_segments = 8
x = np.random.randn(n) # data
rx = np.correlate(x, x, mode='same') / n # ACF
l1 = np.arange(-n//2, n//2) # Lags
segments = x.reshape(n_segments, -1)
m = segments.shape[1]
rs = []
for y in segments:
ry = np.correlate(y, y, mode='same') / m # partial ACF
rs.append(ry)
l2 = np.arange(-m//2, m//2) # lags of partial ACFs
plt.plot(l1, rx, label='full ACF')
plt.plot(l2, np.mean(rs, axis=0), label='partial ACF')
plt.xlim(-m, m)
plt.legend()
plt.show()
import matplotlib.pyplot as plt
import numpy as np
for n in [2**6, 2**8, 2**12]:
x = np.random.randn(n)
rx = np.correlate(x, x, mode='same') / n # ACF
l1 = np.arange(-n//2, n//2) # Lags
plt.plot(l1, rx, label='n={}'.format(n))
plt.legend()
plt.xlim(-20, 20)
plt.show()