这是一个峰值检测程序,可以按我的意愿运行。但是,我想让它更灵活。
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
个元素?
答案 0 :(得分:2)
您可以将range
与slice
一起使用来构建参数列表,然后使用解压(使用*
)将其传递给{{1} }:
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
一起使用以创建新的切片切片:< / p>
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)
在最短子列表耗尽时停止(在这种情况下是最后一个切片),您可以考虑使用itertools.izip_longest
。< / p>
答案 1 :(得分:1)
如果需要对迭代器而不是列表执行shift操作,可以使用itertools.tee()
创建n
移位迭代器,如:
<强>代码:强>
import itertools as it
def shift(an_iter, n):
iters = it.tee(an_iter, n)
for i in range(n):
for _ in range(i):
# remove the first i elements
next(iters[i])
return zip(*iters)
测试代码:
for i in shift('abcdefghij', 5):
print(i)
<强>结果:强>
('a', 'b', 'c', 'd', 'e')
('b', 'c', 'd', 'e', 'f')
('c', 'd', 'e', 'f', 'g')
('d', 'e', 'f', 'g', 'h')
('e', 'f', 'g', 'h', 'i')
('f', 'g', 'h', 'i', 'j')