在数字序列上滑动 window
Sliding window over numerical sequence
我正在尝试构建一种滑动 window 方法,它将滑过列表中元素的数字序列。这很重要,而且我相信它不同于 SO 中发现的其他滑动 window 方法,后者通常在列表的索引上进行滑动。
我的意思是像下面这样。拥有整数列表
li = [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
使用 window=3
和 step=2
,预期输出将是:
[1, 3]
[3, 4, 5]
[5, 6, 7]
[7, 8, 9]
[9, 10, 11]
[11, 12]
我目前的代码:
window = 3
step = 2
last_pos = 0
w_start = 1
w_end = window
next_start = w_start + step
dat = [] # values for window
next_dat = [] # values for the next window
li = [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
for e in li:
ipos = int(e)
if ipos > last_pos:
dat.append(ipos)
if ipos == w_end: # end of window
w_start += step
w_end += step
print(dat)
dat = next_dat # reset window...
if ipos >= next_start: # ipos is in the next window
next_dat.append(ipos)
if w_start == next_start: # move next window
next_start += step
next_dat = [] # reset next window...
else:
raise Exception('List is not sorted')
last_pos += 1
# the last window if not empty
print(dat) if dat else 'false'
输出是预期的:
[1, 3]
[3, 4, 5]
[5, 6, 7]
[7, 8, 9]
[9, 10, 11]
[11, 12]
然而,除了不太优雅之外,当超过两个 windows 重叠时,这段代码似乎会失败。例如,使用 window=5
和 step=2
会产生错误的输出:
[1, 3, 4, 5]
[3, 4, 5, 6, 7]
[6, 7, 8, 9]
[8, 9, 10, 11]
[10, 11, 12]
第一个和第二个windows还可以,但是从第三个开始,事情就变得混乱了。例如,第三个 window 应该从 5
开始并且应该有 5 个元素,而不是四个。我的目标是获得以下 windows:
[1, 3, 4, 5]
[3, 4, 5, 6, 7]
[5, 6, 7, 8, 9]
[7, 8, 9, 10, 11]
[9, 10, 11, 12]
关于如何解决此问题的任何想法?
请注意,滑动的不是列表索引,而是列表值本身。我相信这两种方法在列表中缺少某些值的特定情况下是不同的。在上面显示的情况下,列表中的前三项是 1, 3, 4
。我认为遍历索引(window=2
和 step=2
)会产生以下输出(但未测试):
[1, 3]
[4]
而我想做的是遍历列表的值,这样得到的 windows 将是:
[1]
[3, 4]
因此第一个 window 中缺少值 2
,因为它不在原始列表中。
虽然这里最后用一个列表进行了说明,但我想从一个几乎无法放入内存的大文件中读取这些文件。
问题中代码的问题是不确定您需要事先跟踪多少 windows。
此任务的最佳方法可能只使用一个列表作为 window,然后复制那些与下一个 window 重叠的值,依此类推。
下面的代码适用于我测试的所有 windows:
window = 3
step = 2
last_pos = 0
w_start = 1
w_end = window
dat = [] # values for window
next_dat = [] # values for the next window
li = [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
for e in li:
ipos = int(e)
if ipos > last_pos:
if ipos > w_end: # end of window
print(dat)
w_start += step
w_end += step
if step == window: # non-overlapping
next_dat = [] # reset next window...
else:
next_dat = [x for x in dat if x >= (w_start)]
dat = next_dat # reset window...
dat.append(ipos)
else:
raise Exception('List is not sorted')
last_pos += 1
# the last window if not empty
print(dat) if dat else 'false'
(window=3 且步骤=2)
[1, 3]
[3, 4, 5]
[5, 6, 7]
[7, 8, 9]
[9, 10, 11]
[11, 12]
(window=2 且步长=2)
[1]
[3, 4]
[5, 6]
[7, 8]
[9, 10]
[11, 12]
(window=5 且步骤=2)
[1, 3, 4, 5]
[3, 4, 5, 6, 7]
[5, 6, 7, 8, 9]
[7, 8, 9, 10, 11]
[9, 10, 11, 12]
同样,我认为这段代码不是很优雅,但它完成了工作,所以我将把这个答案标记为已接受。但是,对于此代码,我仍然愿意 improvements/advises。
我正在尝试构建一种滑动 window 方法,它将滑过列表中元素的数字序列。这很重要,而且我相信它不同于 SO 中发现的其他滑动 window 方法,后者通常在列表的索引上进行滑动。
我的意思是像下面这样。拥有整数列表
li = [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
使用 window=3
和 step=2
,预期输出将是:
[1, 3]
[3, 4, 5]
[5, 6, 7]
[7, 8, 9]
[9, 10, 11]
[11, 12]
我目前的代码:
window = 3
step = 2
last_pos = 0
w_start = 1
w_end = window
next_start = w_start + step
dat = [] # values for window
next_dat = [] # values for the next window
li = [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
for e in li:
ipos = int(e)
if ipos > last_pos:
dat.append(ipos)
if ipos == w_end: # end of window
w_start += step
w_end += step
print(dat)
dat = next_dat # reset window...
if ipos >= next_start: # ipos is in the next window
next_dat.append(ipos)
if w_start == next_start: # move next window
next_start += step
next_dat = [] # reset next window...
else:
raise Exception('List is not sorted')
last_pos += 1
# the last window if not empty
print(dat) if dat else 'false'
输出是预期的:
[1, 3]
[3, 4, 5]
[5, 6, 7]
[7, 8, 9]
[9, 10, 11]
[11, 12]
然而,除了不太优雅之外,当超过两个 windows 重叠时,这段代码似乎会失败。例如,使用 window=5
和 step=2
会产生错误的输出:
[1, 3, 4, 5]
[3, 4, 5, 6, 7]
[6, 7, 8, 9]
[8, 9, 10, 11]
[10, 11, 12]
第一个和第二个windows还可以,但是从第三个开始,事情就变得混乱了。例如,第三个 window 应该从 5
开始并且应该有 5 个元素,而不是四个。我的目标是获得以下 windows:
[1, 3, 4, 5]
[3, 4, 5, 6, 7]
[5, 6, 7, 8, 9]
[7, 8, 9, 10, 11]
[9, 10, 11, 12]
关于如何解决此问题的任何想法?
请注意,滑动的不是列表索引,而是列表值本身。我相信这两种方法在列表中缺少某些值的特定情况下是不同的。在上面显示的情况下,列表中的前三项是 1, 3, 4
。我认为遍历索引(window=2
和 step=2
)会产生以下输出(但未测试):
[1, 3]
[4]
而我想做的是遍历列表的值,这样得到的 windows 将是:
[1]
[3, 4]
因此第一个 window 中缺少值 2
,因为它不在原始列表中。
虽然这里最后用一个列表进行了说明,但我想从一个几乎无法放入内存的大文件中读取这些文件。
问题中代码的问题是不确定您需要事先跟踪多少 windows。 此任务的最佳方法可能只使用一个列表作为 window,然后复制那些与下一个 window 重叠的值,依此类推。
下面的代码适用于我测试的所有 windows:
window = 3
step = 2
last_pos = 0
w_start = 1
w_end = window
dat = [] # values for window
next_dat = [] # values for the next window
li = [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
for e in li:
ipos = int(e)
if ipos > last_pos:
if ipos > w_end: # end of window
print(dat)
w_start += step
w_end += step
if step == window: # non-overlapping
next_dat = [] # reset next window...
else:
next_dat = [x for x in dat if x >= (w_start)]
dat = next_dat # reset window...
dat.append(ipos)
else:
raise Exception('List is not sorted')
last_pos += 1
# the last window if not empty
print(dat) if dat else 'false'
(window=3 且步骤=2)
[1, 3]
[3, 4, 5]
[5, 6, 7]
[7, 8, 9]
[9, 10, 11]
[11, 12]
(window=2 且步长=2)
[1]
[3, 4]
[5, 6]
[7, 8]
[9, 10]
[11, 12]
(window=5 且步骤=2)
[1, 3, 4, 5]
[3, 4, 5, 6, 7]
[5, 6, 7, 8, 9]
[7, 8, 9, 10, 11]
[9, 10, 11, 12]
同样,我认为这段代码不是很优雅,但它完成了工作,所以我将把这个答案标记为已接受。但是,对于此代码,我仍然愿意 improvements/advises。