2017-07-07 71 views
0

我有一個Python列表中的29400個值,我試圖檢查列表中的每個元素是否大於其左邊的2000個鄰居以及其右邊的2000個鄰居。如果元素大於它的4000個鄰居,我想檢索元素的索引。如果右邊沒有2000個鄰居,我只想將它與未來的元素進行比較,直到我到達列表的末尾,反之亦然,如果沒有2000個值到左側。將列表中的元素與其鄰居進行比較

def find_peaks(t): 
prev = [] 
future = [] 
peak_index = [] 
for i in range(len(t)-2000): # compare element with previous values 
    for j in range(1,2001): 
     if t[i]<t[i+j]: 
      prev.append(False) 
      break 
     if j==2000: 
      if t[i]<t[i+j]: 
       prev.append(False) 
       break 
      prev.append(True) 

for i in range(1999,len(t)-1): # compare element with future values 
    for j in range(1,2001): 
     if t[i]<t[i-j]: 
      future.append(False) 
      break 
     if j==2000: 
      if t[i]<t[i-j]: 
       future.append(False) 
       break 
      future.append(True) 
future = future[::-1] # reverse list 
for i in range(0,len(prev)-1): 
    if prev[i] == True: 
     if prev[i] == True: 
      peak_index.append(i) 

有沒有人知道有更好的方法去做這件事?我在比較列表結尾和列表開頭附近的元素時遇到了困難 - 如果列表中沒有剩餘2000個元素供我比較,那麼列表將環繞到列表的開頭,這不是某種東西我想要。

+0

你想要爲你的列表循環行爲。我的意思是說,如果在列表中可以說10k元素,並且比較第一個元素,那麼在它的左邊沒有要比較的元素。所以你想以驚人的順序將它與後端進行比較?或者你不用在左邊比較它呢?我已經說清楚了嗎? –

+0

不,我不想要循環行爲。如果我比較說,第三個元素,我只想將它與左側的第一個和第二個元素進行比較,右側是2000個元素。我是一般的Python和編程新手,可能有更簡單的方法去實現它,我只是不知道。 – Ca01an

+0

好的,我明白了你的意思,謝謝澄清。 –

回答

1

你可以使用一些列表理解,所以實際的搜索變成一行。我無法判斷速度和美感,但我的機器只需要幾秒鐘。

import random 

# create list of random numbers and manually insert two peaks 
t = [random.randrange(1, 1000) for r in range(29400)] # found this here: https://stackoverflow.com/questions/16655089/python-random-numbers-into-a-list 
t[666] = 2000 
t[6666] = 2000 

# finds the peak elements 
peaks = [index for index, value in enumerate(t) if value == max(t[max(index-2000, 0):min(index+2000, len(t))])] 
print peaks # includes 666 and 6666 
0

一個天真的,迭代版本將要經過的每個元素都向後看/提前看到的一定次數,如果有比它更大的價值,如果不是認爲這是一個選秀:

def find_peaks(data, span=2000): 
    peaks = [] 
    for i, value in enumerate(data): 
     peak = False # start with the assumed non-peak 
     for j in range(max(0, i - 1), max(0, i - span - 1), -1): # look behind 
      peak = value > data[j] # check if our value is larger than the selected neighbor 
      if not peak: # not a peak, break away 
       break 
     if peak: # look behind passed, look ahead: 
      for j in range(i + 1, min(i + span + 1, len(data))): 
       if value <= data[j]: # look ahead failed, break away 
        peak = False 
        break 
      if peak: # if look ahead passed... 
       peaks.append(i) # add it to our peaks list 
    return peaks 

這是最高效的方式來執行它與前瞻/後面,因爲它不會滿足條件時立即脫離,而不是檢查與每個元素的每個元素。

如果要在計算峯值時計算相同值的鄰居(因此您當前的候選峯值相同),可以在後面的部分中使用peak = value >= data[j],在後面部分中使用。

0

我的解決方案不涉及任何語言強大的內置方法。它只是簡單的邏輯來找到目標峯值。基本上我迭代每個元素,然後在內部循環檢查它的前一個或未來的鄰居是否存在並且小於當前元素。我正在初始化一個isPeak變量爲True,因爲如果兩個方向上的鄰居都沒有大於當前元素,這表明您當前的元素是峯值元素。之後,獲取目標元素的索引。

def find_peaks(t , neighbour_length=2000): 
    peak_index = [] 
    for i in range(len(t)): # compare element with previous values 
     isPeak = True #intialize to true 
     for j in range(i, neighbour_length + i): 

      # Check if previous index value is present 
      if (2*i-j-1 >= 0): 
       # Check if next neighbour is less or break 
       if(t[i] <= t[2*i-j-1]): 
        isPeak = False 
        break 
      # Check if Future element is present 
      if (j+i+1 < len(t)): 
       #Check if next future neighbour ir less or break 
       if(t[i] <= t[i+j+1]): 
        isPeak = False 
        break 

     if(isPeak): 
      peak_index.append(i) 

    return peak_index 

希望它有助於!

相關問題