2017-04-26 84 views
2

鑑於[1,2,3,4,5,6,7,8,9,10],同時獲得3項的滑動窗口來獲得:跳過滑動窗口

[(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7), (6, 7, 8), (7, 8, 9), (8, 9, 10)] 

https://stackoverflow.com/q/42220614/610569,可以實現一個序列的滑動窗口:

def per_window(sequence, n=1): 
    """ 
    Returns a sliding window. 
    From https://stackoverflow.com/q/42220614/610569 
     >>> list(per_window([1,2,3,4], n=2)) 
     [(1, 2), (2, 3), (3, 4)] 
     >>> list(per_window([1,2,3,4], n=3)) 
     [(1, 2, 3), (2, 3, 4)] 
    """ 
    start, stop = 0, n 
    seq = list(sequence) 
    while stop <= len(seq): 
     yield tuple(seq[start:stop]) 
     start += 1 
     stop += 1 

但是,如果有一些限制,我想提出的滑動窗口,而我只是想將某個組件中存在的窗口。

比方說,我只想要一個包含4窗戶,我可以是這樣的:

>>> [window for window in per_window(x, 3) if 4 in window] 
[((2, 3, 4), (3, 4, 5), (4,5,6)] 

但透過如果條件莫名其妙環路仍然有通過窗戶的整個列表,以處理和檢查。

我可以通過查找4的位置並將輸入限制爲per_window(例如,

# Input sequence. 
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
# Window size. 
n = 3 
# Constraint. 
c = 4 
# Set the index to 0 
i = 0 
while i < len(x)-n: 
    i = x.index(4, i) 
    # First window where the constraint is met. 
    left = i - (n-1) 
    if left > 0: 
     print (list(per_window(x[left:i], 3))) 
    right = i + n 
    if right < len(x): 
     print (list(per_window(x[i:right], 3))) 
    i = right 

(注意上面的代碼與IFS不工作=()

相反找到per_window功能外的索引的,有另一種方法在功能per_window添加這樣的限制?


EDITED

閱讀@ RaymondHettinger的回答後:

def skipping_window(sequence, target, n=3): 
    """ 
    Return a sliding window with a constraint to check that 
    target is inside the window. 
    From https://stackoverflow.com/q/43626525/610569 
    """ 
    start, stop = 0, n 
    seq = list(sequence) 
    while stop <= len(seq): 
     subseq = seq[start:stop] 
     if target in subseq: 
      yield tuple(seq[start:stop]) 
     start += 1 
     stop += 1 
     # Fast forwarding the start. 
     # Find the next window which contains the target. 
     try: 
      # `seq.index(target, start) - (n-1)` would be the next 
      # window where the constraint is met. 
      start = max(seq.index(target, start) - (n-1), start) 
      stop = start + n 
     except ValueError: 
      break 

[OUT]:

>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
>>> list(skipping_window(x, 4, 3)) 
[(2, 3, 4), (3, 4, 5), (4, 5, 6)] 

回答

3

找到per_window功能外的索引代替,有另一種方法在功能per_window添加這樣的限制?

是的,你可以在收益率前添加條件:

def per_window(sequence, target, n=1): 
    start, stop = 0, n 
    seq = list(sequence) 
    while stop <= len(seq): 
     subseq = seq[start:stop] 
     if target in subseq: 
      yield tuple(subseq) 
     start += 1 
     stop += 1 
+0

但是,這仍然會通過各種可能的窗口循環,只是它不一樣,如果它失敗的約束,沒有屈服? =( – alvas

+1

給出的答案問的問題相匹配。另外,很顯然,你已經通過使用*指數()*快速前進到下一個可能匹配的子知道路徑進一步優化。 –

+1

謝謝@RaymondHettinger!只需要確認不包括「快進」優化,我在考慮是否遺漏了某些東西=) – alvas