首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用numpy.correlate进行自相关?

如何使用numpy.correlate进行自相关?
EN

Stack Overflow用户
提问于 2009-03-13 17:07:53
回答 12查看 224K关注 0票数 125

我需要对一组数字进行自相关,据我所知,这只是一组数字与其自身的相关性。

我试过使用numpy的相关函数,但我不相信结果,因为它几乎总是给出一个向量,其中第一个数字不是最大的,因为它应该是最大的。

所以,这个问题实际上是两个问题:

  1. numpy.correlate到底在做什么?
  2. 我怎样才能使用它(或其他东西)来做auto-correlation?
EN

回答 12

Stack Overflow用户

发布于 2011-11-02 21:27:38

自相关有两个版本:统计和卷积。它们都做同样的事情,除了一个小细节:统计版本被归一化为区间-1,1。下面是一个如何做统计版本的例子:

代码语言:javascript
复制
def acf(x, length=20):
    return numpy.array([1]+[numpy.corrcoef(x[:-i], x[i:])[0,1]  \
        for i in range(1, length)])
票数 33
EN

Stack Overflow用户

发布于 2018-07-04 15:32:41

我认为有两件事增加了这个话题的混乱:

  1. 统计v.s.信号处理定义:正如其他人所指出的,在统计学中,我们将自相关归一化为-1,1.
  2. 部分vs.非部分均值/方差:当时间序列以lag>0移位时,它们的重叠大小总是小于原始长度。我们是使用原始(非部分)的均值和标准差,还是总是使用不断变化的重叠(部分)来计算新的均值和标准差。(这可能有一个正式的术语,但我现在将使用“部分”)。

我已经创建了5个函数来计算一维数组的自相关,具有部分和非部分区别。一些人使用统计学中的公式,一些人使用信号处理意义上的相关,这也可以通过FFT来完成。但在统计定义中,所有结果都是自相关的,因此它们说明了它们是如何相互链接的。代码如下:

代码语言:javascript
复制
import numpy
import matplotlib.pyplot as plt

def autocorr1(x,lags):
    '''numpy.corrcoef, partial'''

    corr=[1. if l==0 else numpy.corrcoef(x[l:],x[:-l])[0][1] for l in lags]
    return numpy.array(corr)

def autocorr2(x,lags):
    '''manualy compute, non partial'''

    mean=numpy.mean(x)
    var=numpy.var(x)
    xp=x-mean
    corr=[1. if l==0 else numpy.sum(xp[l:]*xp[:-l])/len(x)/var for l in lags]

    return numpy.array(corr)

def autocorr3(x,lags):
    '''fft, pad 0s, non partial'''

    n=len(x)
    # pad 0s to 2n-1
    ext_size=2*n-1
    # nearest power of 2
    fsize=2**numpy.ceil(numpy.log2(ext_size)).astype('int')

    xp=x-numpy.mean(x)
    var=numpy.var(x)

    # do fft and ifft
    cf=numpy.fft.fft(xp,fsize)
    sf=cf.conjugate()*cf
    corr=numpy.fft.ifft(sf).real
    corr=corr/var/n

    return corr[:len(lags)]

def autocorr4(x,lags):
    '''fft, don't pad 0s, non partial'''
    mean=x.mean()
    var=numpy.var(x)
    xp=x-mean

    cf=numpy.fft.fft(xp)
    sf=cf.conjugate()*cf
    corr=numpy.fft.ifft(sf).real/var/len(x)

    return corr[:len(lags)]

def autocorr5(x,lags):
    '''numpy.correlate, non partial'''
    mean=x.mean()
    var=numpy.var(x)
    xp=x-mean
    corr=numpy.correlate(xp,xp,'full')[len(x)-1:]/var/len(x)

    return corr[:len(lags)]


if __name__=='__main__':

    y=[28,28,26,19,16,24,26,24,24,29,29,27,31,26,38,23,13,14,28,19,19,\
            17,22,2,4,5,7,8,14,14,23]
    y=numpy.array(y).astype('float')

    lags=range(15)
    fig,ax=plt.subplots()

    for funcii, labelii in zip([autocorr1, autocorr2, autocorr3, autocorr4,
        autocorr5], ['np.corrcoef, partial', 'manual, non-partial',
            'fft, pad 0s, non-partial', 'fft, no padding, non-partial',
            'np.correlate, non-partial']):

        cii=funcii(y,lags)
        print(labelii)
        print(cii)
        ax.plot(lags,cii,label=labelii)

    ax.set_xlabel('lag')
    ax.set_ylabel('correlation coefficient')
    ax.legend()
    plt.show()

下面是输出图:

我们看不到全部5条线,因为它们中的3条重叠(在紫色处)。重叠都是非部分自相关。这是因为信号处理方法(np.correlate,快速傅立叶变换)的计算不会为每个重叠计算不同的均值/标准差。

还要注意,fft, no padding, non-partial (红线)结果是不同的,因为它在执行快速傅立叶变换之前没有用0填充时间序列,所以它是循环快速傅立叶变换。我不能详细解释原因,这是我从其他地方学到的。

票数 26
EN

Stack Overflow用户

发布于 2014-02-19 03:10:38

使用numpy.corrcoef函数而不是numpy.correlate来计算滞后t的统计相关性:

代码语言:javascript
复制
def autocorr(x, t=1):
    return numpy.corrcoef(numpy.array([x[:-t], x[t:]]))
票数 24
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/643699

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档