876*_*674 29 python signal-processing numpy
我想对下面显示的信号执行自相关.两个连续点之间的时间是2.5ms(或400Hz的重复率).
这是我想要使用的估计自相关的等式(取自http://en.wikipedia.org/wiki/Autocorrelation,部分估计):
在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()
Run Code Online (Sandbox Code Playgroud)
unu*_*tbu 29
我不认为这个特定计算有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
Run Code Online (Sandbox Code Playgroud)
assert语句用于检查计算并记录其意图.
当您确信此函数的行为符合预期时,您可以注释掉该assert
语句,或者运行您的脚本python -O
.(该-O
标志告诉Python忽略断言语句.)
Kat*_*mar 16
我从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
Run Code Online (Sandbox Code Playgroud)
ham*_*ogu 11
statsmodels包添加了一个内部使用的自相关函数np.correlate
(根据statsmodels
文档).
请参阅:http: //statsmodels.sourceforge.net/stable/generated/statsmodels.tsa.stattools.acf.html#statsmodels.tsa.stattools.acf
我写我的最新编辑的方法是比现在还要快scipy.statstools.acf
用fft=True
,直到试样尺寸变得非常大.
错误分析如果您想调整偏差并获得高度准确的错误估计:请查看我的代码,该代码由Ulli Wolff (或UW原创)实施本文Matlab
a = correlatedData(n=10000)
来自这里的常规gamma()
来自同一个地方 correlated_data()
acorr()
是我的功能如下estimated_autocorrelation
在另一个答案中找到acf()
来自 from statsmodels.tsa.stattools import acf
%timeit a0, junk, junk = gamma(a, f=0) # puwr.py
%timeit a1 = [acorr(a, m, i) for i in range(l)] # my own
%timeit a2 = acf(a) # statstools
%timeit a3 = estimated_autocorrelation(a) # numpy
%timeit a4 = acf(a, fft=True) # stats FFT
## -- End pasted text --
100 loops, best of 3: 7.18 ms per loop
100 loops, best of 3: 2.15 ms per loop
10 loops, best of 3: 88.3 ms per loop
10 loops, best of 3: 87.6 ms per loop
100 loops, best of 3: 3.33 ms per loop
Run Code Online (Sandbox Code Playgroud)
编辑...我再次检查保持l=40
并更改n=10000
为n=200000
样本FFT方法开始获得一点牵引力和statsmodels
fft实现只是边缘...(顺序是相同的)
## -- End pasted text --
10 loops, best of 3: 86.2 ms per loop
10 loops, best of 3: 69.5 ms per loop
1 loops, best of 3: 16.2 s per loop
1 loops, best of 3: 16.3 s per loop
10 loops, best of 3: 52.3 ms per loop
Run Code Online (Sandbox Code Playgroud)
编辑2:我改变了我的例程并重新测试了FFT n=10000
和forn=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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
4x
加速可以在下面实现.你必须小心,只传递op_samples=a.copy()
,因为它会修改数组a
通过a-=mean
其他方式:
op_samples -= mean
return (op_samples[:op_samples.size-separation]*op_samples[separation:]).ravel().mean() / norm
Run Code Online (Sandbox Code Playgroud)
这有点超出了范围,但是如果没有集成的自相关时间或积分窗口计算,我就不会为重做这个数字而烦恼.底部图中清楚地显示了具有错误的自相关