用Python估计自相关

用Python估计自相关,python,numpy,signal-processing,Python,Numpy,Signal Processing,我想对下面显示的信号执行自相关。两个连续点之间的时间为2.5ms(或400Hz的重复频率) 这是我想使用的估算autoacrrelation的公式(摘自“估算”一节): 在python中查找数据估计自相关的最简单方法是什么?我可以使用类似于numpy.correlate的东西吗 或者我应该只计算均值和方差吗 编辑: 在他的帮助下,我写了: from numpy import * import numpy as N import pylab as P fn = 'data.txt' x =

我想对下面显示的信号执行自相关。两个连续点之间的时间为2.5ms(或400Hz的重复频率)

这是我想使用的估算autoacrrelation的公式(摘自“估算”一节):

在python中查找数据估计自相关的最简单方法是什么?我可以使用类似于
numpy.correlate
的东西吗

或者我应该只计算均值和方差吗


编辑:

在他的帮助下,我写了:

from numpy import *
import numpy as N
import pylab as P

fn = 'data.txt'
x = loadtxt(fn,unpack=True,usecols=[1])
time = loadtxt(fn,unpack=True,usecols=[0]) 

def estimated_autocorrelation(x):
    n = len(x)
    variance = x.var()
    x = x-x.mean()
    r = N.correlate(x, x, mode = 'full')[-n:]
    #assert N.allclose(r, N.array([(x[:n-k]*x[-(n-k):]).sum() for k in range(n)]))
    result = r/(variance*(N.arange(n, 0, -1)))
    return result

P.plot(time,estimated_autocorrelation(x))
P.xlabel('time (s)')
P.ylabel('autocorrelation')
P.show()

我不认为有一个NumPy函数用于这个特殊的计算。我会这样写:

def estimated_autocorrelation(x):
    """
    http://stackoverflow.com/q/14297012/190597
    http://en.wikipedia.org/wiki/Autocorrelation#Estimation
    """
    n = len(x)
    variance = x.var()
    x = x-x.mean()
    r = np.correlate(x, x, mode = 'full')[-n:]
    assert np.allclose(r, np.array([(x[:n-k]*x[-(n-k):]).sum() for k in range(n)]))
    result = r/(variance*(np.arange(n, 0, -1)))
    return result
assert语句用于检查计算并记录其意图


当您确信此函数的行为符合预期时,可以注释掉
assert
语句,或者使用
python-O
运行脚本。(
-O
标志告诉Python忽略断言语句。)

statsmodels包添加了一个自相关函数,该函数在内部使用
np.correlate
(根据
statsmodels
文档)

见:

我从pandas autocorrelation_plot()函数中提取了一部分代码。我用R检查了答案,值完全匹配

import numpy
def acf(series):
    n = len(series)
    data = numpy.asarray(series)
    mean = numpy.mean(data)
    c0 = numpy.sum((data - mean) ** 2) / float(n)

    def r(h):
        acf_lag = ((data[:n - h] - mean) * (data[h:] - mean)).sum() / float(n) / c0
        return round(acf_lag, 3)
    x = numpy.arange(n) # Avoiding lag 0 calculation
    acf_coeffs = map(r, x)
    return acf_coeffs

我在最新编辑时编写的方法现在甚至比
scipy.stattools.acf
fft=True
更快,直到样本量变得非常大

错误分析如果您想调整偏差并获得高度准确的错误估计:请看我的代码,它由Ulli Wolff()实现

功能测试
  • a=correlatedData(n=10000)
    来自找到的例程
  • gamma()
    correlated\u data()来自同一位置
  • acorr()
    是我下面的函数
  • 估计的自相关
    可在另一个答案中找到
  • acf()
    来自
    来自statsmodels.tsa.stattools导入acf
时间安排 编辑。。。我再次检查保持
l=40
并将
n=10000
更改为
n=200000
采样FFT方法开始获得一些牵引力,并且
statsmodels
FFT实现正好使其边缘化。。。(顺序相同)

编辑2:我更改了我的例程,并对
n=10000
n=20000

a = correlatedData(n=200000); b=correlatedData(n=10000)
m = a.mean(); rng = np.arange(40); mb = b.mean()
%timeit a1 = map(lambda t:acorr(a, m, t), rng)
%timeit a1 = map(lambda t:acorr.acorr(b, mb, t), rng)
%timeit a4 = acf(a, fft=True)
%timeit a4 = acf(b, fft=True)

10 loops, best of 3: 73.3 ms per loop   # acorr below
100 loops, best of 3: 2.37 ms per loop  # acorr below
10 loops, best of 3: 79.2 ms per loop   # statstools with FFT
100 loops, best of 3: 2.69 ms per loop # statstools with FFT
实施
4x
加速可以在下面实现。您必须小心只传递
op_samples=a.copy()
,因为它将通过
a-=mean
修改数组
a
,否则:

op_samples -= mean
return (op_samples[:op_samples.size-separation]*op_samples[separation:]).ravel().mean() / norm
完整性检查

实例误差分析 这有点超出范围,但如果没有积分自相关时间或积分窗口计算,我就懒得重做这个数字。带有误差的自相关在底部图中清晰可见

我发现这只需稍作改动即可达到预期效果:

def estimated_autocorrelation(x):
    n = len(x)
    variance = x.var()
    x = x-x.mean()
    r = N.correlate(x, x, mode = 'full')
    result = r/(variance*n)
    return result

根据Excel的自相关结果进行测试。

我想更具体地谈谈估计的自相关方程。另请参见:谢谢。我认为这是计算自相关估计的唯一方法。使用
x=loadtxt('fn.txt',unpack=True,usecols=[0])
和绘图
pylab.plot(autoCorr,t)
可以很容易地找到加载数据的自相关性吗?是的,类似的方法应该可以工作。也许可以尝试
pylab.plot(x,estimate_autocorrelation(x))
…您的数据样本太小了,这怎么可能比用于大数据量的fft方法更快?您正在将n^2与nlogn进行比较。请随意重复-代码如上所述。我确实说过FFT例程在很大程度上成为了更快的方法,所以我怀疑你只是扫描了第一句话。FFT方法可能有很多python开销,并且每次调用时都会进行错误检查。抱歉,这样说只是误导,您只需计算40个不同时移的相关性。通常,如果您有一个200000个点的数据集,从性能角度来看,有趣的部分是查看整个时间的相关函数。在本例中,您将处理200000^2的数量级的操作,而FFT方法将处理大约5*200000的操作。顺便说一句,我的朴素实现与您的实现基本相同,在相同的输入上每个循环需要18.1毫秒…首先,感谢您花时间来研究这个问题-我经常使用此代码,因此任何改进都是非常受欢迎的!随着相关时间的增加,样本量会减小,因此,由于在较长时间内缺少样本,因此测量所有时间没有多大帮助。您能否澄清您正在计时的方法,并用另一种方法对其进行基准测试?(不同的机器等)为了澄清,我同意FFT在规模上更快。然而,对于许多日常案例,示例
nLet会让我们失望。
def acorr(op_samples, mean, separation, norm = 1):
    """autocorrelation of a measured operator with optional normalisation
    the autocorrelation is measured over the 0th axis

    Required Inputs
        op_samples  :: np.ndarray :: the operator samples
        mean        :: float :: the mean of the operator
        separation  :: int :: the separation between HMC steps
        norm        :: float :: the autocorrelation with separation=0
    """
    return ((op_samples[:op_samples.size-separation] - mean)*(op_samples[separation:]- mean)).ravel().mean() / norm
op_samples -= mean
return (op_samples[:op_samples.size-separation]*op_samples[separation:]).ravel().mean() / norm
def estimated_autocorrelation(x):
    n = len(x)
    variance = x.var()
    x = x-x.mean()
    r = N.correlate(x, x, mode = 'full')
    result = r/(variance*n)
    return result