2017-04-24 84 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:]) 

如果w=n,其中n是奇數的話,我想這一點:

xt=zip(x,x[1:],x[2:],...,x[n:]) 
yt=zip(y,y[1:],y[2:],...,y[n:]) 

那麼,如何建立這些陣列,其中每個元素包含n元素其他陣列?

回答

2

您可以使用rangeslice打造的參數列表,然後使用拆包(與*)到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)]) 

在這種情況下,你可以是具有兩個以上的維度,建立一次切片列表可能會更好,然後與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) 

在另一方面,因爲你的清單參數的大小不是恆定的,zip停止時最短的子列表耗盡(在這種情況下,最後的片),你可以考慮使用itertools.izip_longest

1

如果你需要做一個迭代器而不是列表中的換檔操作,您可以使用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')