这是一个峰值检测例程,可以根据需要运行.但是,我想使其更加灵活.
def peak2(x,y,dp,dv):
# Define two arrays: one for the peaks and one
# for the valleys
peaks=[]
valleys=[]
# Create two arrays, one for x, and one for y, where each
# element of the new array # consists of three adjacent
# elements of the old array.
xt=zip(x,x[1:],x[2:])
yt=zip(y,y[1:],y[2:])
# Walk through these arrays, checking to see if the middle
# value of the three old elements exceeds its neighbors by
# d or more.
idx=1
for i,j in zip(xt,yt):
if(j[1]-j[0]>dp and j[1]-j[2]>dp):
peaks.append((x[idx],y[idx]))
elif (j[0]-j[1]>dv and j[2]-j[1]>dv):
valleys.append((x[idx],y[idx]))
idx+=1
return array(peaks),array(valleys)
如您所见,它通过将一个值与其左右邻居进行比较来检测一个峰.并且,如果中心值比其两个紧邻的中心都大某个阈值,则将其视为峰值.寻找山谷的类似逻辑.
我想扩展它,以便将中心值与每一侧的n个邻居进行比较.我将参数传递给函数(称为w),如果w = 3,则执行以下操作:
xt=zip(x,x[1:],x[2:])
yt=zip(y,y[1:],y[2:])
这是当前例程中的内容.但是如果w = 5,那么我想要这个:
xt=zip(x,x[1:],x[2:],x[3:],x[4:])
yt=zip(y,y[1:],y[2:],y[3:],y[4:])
如果w = n,其中n是奇数,那么我想要这个:
xt=zip(x,x[1:],x[2:],...,x[n:])
yt=zip(y,y[1:],y[2:],...,y[n:])
那么,如何在每个元素包含其他数组的n个元素的情况下构建这些数组呢?
解决方法:
您可以使用带有slice的range来构建参数列表,然后使用解包(带有*)将其传递给zip:
xt = zip(*[x[slice(i, None)] for i in xrange(n)]) # use range in Python 3
yt = zip(*[y[slice(i, None)] for i in xrange(n)])
如果您可能有两个以上的维度,则最好一次构建切片列表,然后将其与map和list .__ getitem__一起使用以创建新的列表切片:
slices = [slice(i, None) for i in xrange(n)]
xt = zip(*map(x.__getitem__, slices)
yt = zip(*map(y.__getitem__, slices)
zt = zip(*map(z.__getitem__, slices)
另外请注意,由于列表参数的大小不是恒定的,并且在最短的子列表用尽时(此情况下为最后一个切片),zip会停止,因此您可以考虑使用itertools.izip_longest
.