subset(("A","b","C","D"))
次の結果が得られます。
("A","b","C"),
("b","C","D"),
("A","b"),
("b","C"),
("C","D"),
("A",),
("b",),
("C",),
("D",)
スライドウィンドウは難しい場合があります。ウィンドウを繰り返し縮小または拡大すると、2 倍になります。
解決する手順をリストすることから始めて、それらの手順に従う関数を作成します。
- 最大のウィンドウ サイズから開始します (コード例から、全長より 1 小さいサイズ)。
- 次に、データセットをカバーするために必要なウィンドウの数を計算します。
- 次に、ウィンドウごとに、番号を開始インデックスとして再利用できます。開始インデックスをウィンドウ サイズに追加して、各ウィンドウが停止する場所を特定する必要があります。
結果の関数:
def subset(data):
total_length = len(data)
for window_length in range(total_length - 1, 0, -1): # biggest first
n_windows = total_length - window_length + 1
for each_window in range(n_windows):
start = each_window
stop = start + window_length
yield data[start:stop]
サンプルデータ:
data = ("A","b","C","D")
subset
そして、 onを呼び出すとdata
、ジェネレータが返されます。これを に渡すとlist
、結果が具体化されます。
>>> subset(data)
<generator object subset at 0x7fbc3d7f3570>
>>> list(subset(data))
[('A', 'b', 'C'), ('b', 'C', 'D'), ('A', 'b'), ('b', 'C'), ('C', 'D'), ('A',), ('b',), ('C',), ('D',)]
Deque ソリューション:
ローリング ウィンドウに (コレクション モジュールの) deque を使用するというアイデアに魅了され、これを実演することにしました。
import collections
import pprint
def shrinking_windows(iterable):
'''
Given an ordered iterable (meaningless for unordered ones)
return a list of tuples representing each possible set
of consecutive items from the original list. e.g.
shrinking_windows(['A', 'b', 'c']) returns
[('A', 'b', 'c'), ('A', 'b'), ('b', 'c') ...] but not ('A', 'c')
'''
window_generator = range(len(iterable), 0, -1)
results = []
for window in window_generator:
d = collections.deque((), maxlen=window)
for i in iterable:
d.append(i)
if len(d) == window:
results.append(tuple(d))
return results
pprint.pprint(shrinking_windows('AbCd'))
うまく戻ります:
[('A', 'b', 'C', 'd'),
('A', 'b', 'C'),
('b', 'C', 'd'),
('A', 'b'),
('b', 'C'),
('C', 'd'),
('A',),
('b',),
('C',),
('d',)]