2017-04-24 10 views
3

私が望むように動作するピーク検出ルーチンがあります。しかし、私はより柔軟にしたいです。可変幅のサイズを持つPythonのピーク検出

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:]) 

そしてnが奇数のw=n、なら、私はこれ欲しい:

だから私は、各要素が nの要素が含まれ、これらの配列を構築することができますどのように
xt=zip(x,x[1:],x[2:],...,x[n:]) 
yt=zip(y,y[1:],y[2:],...,y[n:]) 

他の配列の?

あなたは、引数のリストを作成し、その後 zipに( *で)を開梱 を使用してそれらを渡すためにslicerangeを使用することができます

答えて

2

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)]) 

あなたが二つ以上の寸法を有するすることができる場合、かつてのスライスのリストを作成し、新しいリストのスライスを作成するmaplist.__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) 
01別のノートで

リスト引数のサイズは一定ではなく、最短のサブリストが使い果たされたときzipが(この場合は最後のスライスを)停止しているので、あなたはitertools.izip_longestを使用して検討することができます。

1

あなたの代わりに、リストのイテレータにシフト操作を行う必要がある場合は、あなたのようなnシフトイテレータの作成にitertools.tee()を使用することができます。

コード:

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') 
関連する問題