我有一维数据数据,希望提取空间变化。我希望pythonize的标准方法是对数据执行移动线性回归并保存渐变...
def nssl_kdp(phidp, distance, fitlen):
kdp=zeros(phidp.shape, dtype=float)
myshape=kdp.shape
for swn in range(myshape[0]):
print "Sweep ", swn+1
for rayn in range(myshape[1]):
print "ray ", rayn+1
small=[polyfit(distance[a:a+2*fitlen], phidp[swn, rayn, a:a+2*fitlen],1)[0] for a in xrange(myshape[2]-2*fitlen)]
kdp[swn, rayn, :]=array((list(itertools.chain(*[fitlen*[small[0]], small, fitlen*[small[-1]]]))))
return kdp
效果不错但很慢......我需要这样做17 * 360次......
我认为开销是在[for arange]行中的迭代器中...在numpy / scipy中是否存在移动拟合的实现?
答案 0 :(得分:3)
线性回归的计算基于各种值的总和。因此,您可以编写一个更有效的例程,在窗口移动时修改总和(添加一个点并减去前一个点)。
这比每次窗口移动时重复该过程更有效,但是对于舍入错误是开放的。所以你需要偶尔重启。
通过预先计算所有x依赖关系,你可能比等间距更好,但我不明白你的例子,所以我不确定它是否相关。
所以我想我只是假设它是。
斜率为(NΣXY - (ΣX)(ΣY))/(NΣX2 - (ΣX)2)其中“2”为“平方” - http://easycalculation.com/statistics/learn-regression.php
对于均匀间隔的数据,分母是固定的(因为您可以将x轴移动到窗口的开头而不改变渐变)。分子中的(ΣX)也是固定的(出于同样的原因)。所以你只需要关注ΣXY和ΣY。后者是微不足道的 - 只需添加和减去一个值。前者减少ΣY(每个X加权减少1)并且每步增加(N-1)Y(假设x_0为0,x_N为N-1)。
我怀疑还不清楚。我所说的是斜率的公式不需要在每一步都完全重新计算。特别是因为在每一步中,您可以将X值重命名为0,1,... N-1而不改变斜率。因此,公式中的几乎所有内容都是相同的。所有这些变化都是两个术语,取决于Y,Y_0“退出”窗口,Y_N“移入”。答案 1 :(得分:1)
答案 2 :(得分:1)
好的..我有一个似乎是一个解决方案..不是一个答案,但是一种做出移动,多点差异的方法......我测试了这个,结果看起来非常类似于一个移动回归...我使用了1D sobel滤波器(斜率从-1到1与数据卷积):
def KDP(phidp, dx, fitlen):
kdp=np.zeros(phidp.shape, dtype=float)
myshape=kdp.shape
for swn in range(myshape[0]):
#print "Sweep ", swn+1
for rayn in range(myshape[1]):
#print "ray ", rayn+1
kdp[swn, rayn, :]=sobel(phidp[swn, rayn,:], window_len=fitlen)/dx
return kdp
def sobel(x,window_len=11):
"""Sobel differential filter for calculating KDP
output:
differential signal (Unscaled for gate spacing
example:
"""
s=np.r_[x[window_len-1:0:-1],x,x[-1:-window_len:-1]]
#print(len(s))
w=2.0*np.arange(window_len)/(window_len-1.0) -1.0
#print w
w=w/(abs(w).sum())
y=np.convolve(w,s,mode='valid')
return -1.0*y[window_len/2:len(x)+window_len/2]/(window_len/3.0)
这样跑得快!