如何在 python 中创建一个从较小数组的末尾开始到较小数组的开头结束的滑动 window?
How to create a sliding window that starts at the end of the smaller array and ends at the start of the smaller array in python?
我有 2 个数组:
[7, 6, 9, 8]
[1, 2, 3, 4, 5, 3, 2, 1]
我想像这样滑过它们:
迭代 1:
[7, 6, 9, |8|]
[|1|, 2, 3, 4, 5, 3, 2, 1]
2:
[7, 6, |9, 8|]
[|1, 2|, 3, 4, 5, 3, 2, 1]
3:
[7,|6, 9, 8|]
[|1, 2, 3|, 4, 5, 3, 2, 1]
4:
[|7, 6, 9, 8|]
[|1, 2, 3, 4|, 5, 3, 2, 1]
5:
[|7, 6, 9, 8|]
[1, |2, 3, 4, 5|, 3, 2, 1]
它继续以第一个数组的长度直到...
迭代 9:
[|7, 6, 9|, 8|]
[1, 2, 3, 4, 5, |3, 2, 1|]
10:
[|7, 6|, 9, 8|]
[1, 2, 3, 4, 5, 3, |2, 1|]
11:
[|7|, 6, 9, 8|]
[1, 2, 3, 4, 5, 3, 2, |1|]
我已经尝试了什么?一团糟,根本行不通,恐怕分享它会阻止许多人甚至回应。
编辑:对于那些想看的人来说,这是我的非工作代码:
embedding_list_1 = [[1, 2, 3], [1, 3, 4], [1, 2, 4]]
embedding_list_2 = [[1, 2, 3], [1, 3, 4], [1, 2, 4], [1, 2, 4], [1, 2, 4], [3, 4, 5]]
region_range = 1
first_run = True
increment = True
embedding_list_2_start = 0
embedding_list_2_end = len(embedding_list_1)
while region_range >= 0:
if first_run:
print('Cutting embedding list 1 from:', len(embedding_list_1)-region_range, 'to', len(embedding_list_1))
print(embedding_list_1[len(embedding_list_1)-region_range:])
print('Cutting embedding list 2 from:', 0, 'to', region_range)
embedding_list_2[:region_range]
region_range +=1
first_run = False
else:
chopped_off = embedding_list_1[len(embedding_list_1)-region_range:]
print(chopped_off)
embedding_list_2[embedding_list_2_start:region_range]
if increment:
region_range +=1
if region_range == len(embedding_list_1):
#break
#use full list
print(len(embedding_list_1))
embedding_list_2_start+=1
embedding_list_2_end+=1
print('Cutting embedding list 2 from', embedding_list_2_start, 'to', embedding_list_2_end)
print(embedding_list_2[embedding_list_2_start:embedding_list_2_end])
increment = False
if embedding_list_2_end == len(embedding_list_2):
#Stop incrementing end
#Start negative shift for other embedding
region_range-=1
print('Cutting embedding list 1 from: 0', 'to', region_range)
embedding_list_1[0:region_range]
embedding_list_2_start+=1
embedding_list_2_end+=1
print('cuting embedding list 2 from:', embedding_list_2_start, embedding_list_2_end)
embedding_list_2[:embedding_list_2_end]
这是一个快速但可能相当肮脏的尝试。
第一次迭代中的重叠看起来像这样:
让我们先看看与list2
相关的所有内容。在第一次迭代中
# Calculate the offset between the two lists
offset = 1 - len(list1) # -3
l2_window_start = offset
l2_window_end = 0
# The slice for list2 starts at the larger of 0 and l2_window_start
l2_start = max(0, l2_window_start)
# The slice for list2 ends at the smaller of 7 and l2_window_end
l2_end = min(len(list2) - 1, l2_window_end)
# Add one to l2_end because slices don't contain the end index.
list2_slice = list2[l2_start:l2_end+1]
现在,使用这些数字查看 list1
:
l1_window_start = -offset # starts off at 3
l1_start = max(0, l1_window_start)
# list1 slice needs to have as many elements as list2_slice
l1_end = l1_start + len(list2_slice)
list1_slice = list1[l1_start:l1_end]
随着迭代向前推进,l2_window_start
、l2_window_end
和offset
都增加了1。l1_window_start
减少了1。
将其放入循环中:
list1 = [7, 6, 9, 8]
list2 = [1, 2, 3, 4, 5, 3, 2, 1]
offset = l2_window_start = 1 - len(list1) # -3
l2_window_end = 0
l1_window_start = -offset
l1_window_end = len(list1) - 1
for iternum in range(11):
# The slice for list2 starts at the larger of 0 and l2_window_start
l2_start = max(0, l2_window_start)
# The slice for list2 ends at the smaller of 7 and l2_window_end
l2_end = min(len(list2) - 1, l2_window_end)
# Add one to l2_end because slices don't contain the end index.
list2_slice = list2[l2_start:l2_end+1]
l1_start = max(0, l1_window_start)
l1_end = l1_start + len(list2_slice)
list1_slice = list1[l1_start:l1_end]
print(iternum+1, list1_slice, list2_slice)
l1_window_start -= 1;
l2_window_start += 1; l2_window_end += 1; offset += 1
这给了我们所需的输出:
1 [8] [1]
2 [9, 8] [1, 2]
3 [6, 9, 8] [1, 2, 3]
4 [7, 6, 9, 8] [1, 2, 3, 4]
5 [7, 6, 9, 8] [2, 3, 4, 5]
6 [7, 6, 9, 8] [3, 4, 5, 3]
7 [7, 6, 9, 8] [4, 5, 3, 2]
8 [7, 6, 9, 8] [5, 3, 2, 1]
9 [7, 6, 9] [3, 2, 1]
10 [7, 6] [2, 1]
11 [7] [1]
我的解决方案与@pranav-hosangadi 的回答非常相似(也许最终相同)。我的结果略有不同,因为我的答案是根据每个列表中的窗口元素配对生成元组。
与@pranav-hosangadi 的回答一样,我们从涵盖整张幻灯片的范围开始。棘手的部分(至少对我而言)是制定正确的开始和结束。
a = [7, 6, 9, 8]
b = [1, 2, 3, 4, 5, 3, 2, 1]
a_len = len(a)
b_len = len(b)
for i in range(0, a_len + b_len -1):
a_start = max(0, a_len -i -1)
a_end = min(a_len, a_len + b_len - i)
b_start = max(0, i + 1 - a_len)
b_end = min(i + 1, b_len)
result = [(a[x], b[y]) for (x, y) in zip(range(a_start, a_end), range(b_start, b_end))]
print(result)
这会产生略有不同(错误?)的输出:
[(8, 1)]
[(9, 1), (8, 2)]
[(6, 1), (9, 2), (8, 3)]
[(7, 1), (6, 2), (9, 3), (8, 4)]
[(7, 2), (6, 3), (9, 4), (8, 5)]
[(7, 3), (6, 4), (9, 5), (8, 3)]
[(7, 4), (6, 5), (9, 3), (8, 2)]
[(7, 5), (6, 3), (9, 2), (8, 1)]
[(7, 3), (6, 2), (9, 1)]
[(7, 2), (6, 1)]
[(7, 1)]
这里是使用 zip 函数的一个稍微不同的变体;
l1 = [7, 6, 9, 8]
l2 = [1, 2, 3, 4, 5, 3, 2, 1]
def slide(la, lb):
lxa = []
lxa = [x for x in range(len(la))]
lxa.extend([None]* (len(lb) - 1))
lxb = [None] * (len(la) -1)
lxb.extend([x for x in range(len(lb))])
lxcnt = 0
rslt = []
while lxcnt < len(lxa):
tmp = []
matchs = zip(lxa, lxb)
for mtch in matchs:
if mtch[0] != None and mtch[1] != None:
tmp.append(mtch)
if tmp:
rslt.append(tmp)
lxa.insert(0, None)
lxa = lxa[:-1]
lxcnt += 1
return rslt
运行 slide(l1, l2)
,产量:
[[(3, 0)],
[(2, 0), (3, 1)],
[(1, 0), (2, 1), (3, 2)],
[(0, 0), (1, 1), (2, 2), (3, 3)],
[(0, 1), (1, 2), (2, 3), (3, 4)],
[(0, 2), (1, 3), (2, 4), (3, 5)],
[(0, 3), (1, 4), (2, 5), (3, 6)],
[(0, 4), (1, 5), (2, 6), (3, 7)],
[(0, 5), (1, 6), (2, 7)],
[(0, 6), (1, 7)],
[(0, 7)]]
我有 2 个数组:
[7, 6, 9, 8]
[1, 2, 3, 4, 5, 3, 2, 1]
我想像这样滑过它们:
迭代 1:
[7, 6, 9, |8|]
[|1|, 2, 3, 4, 5, 3, 2, 1]
2:
[7, 6, |9, 8|]
[|1, 2|, 3, 4, 5, 3, 2, 1]
3:
[7,|6, 9, 8|]
[|1, 2, 3|, 4, 5, 3, 2, 1]
4:
[|7, 6, 9, 8|]
[|1, 2, 3, 4|, 5, 3, 2, 1]
5:
[|7, 6, 9, 8|]
[1, |2, 3, 4, 5|, 3, 2, 1]
它继续以第一个数组的长度直到...
迭代 9:
[|7, 6, 9|, 8|]
[1, 2, 3, 4, 5, |3, 2, 1|]
10:
[|7, 6|, 9, 8|]
[1, 2, 3, 4, 5, 3, |2, 1|]
11:
[|7|, 6, 9, 8|]
[1, 2, 3, 4, 5, 3, 2, |1|]
我已经尝试了什么?一团糟,根本行不通,恐怕分享它会阻止许多人甚至回应。
编辑:对于那些想看的人来说,这是我的非工作代码:
embedding_list_1 = [[1, 2, 3], [1, 3, 4], [1, 2, 4]]
embedding_list_2 = [[1, 2, 3], [1, 3, 4], [1, 2, 4], [1, 2, 4], [1, 2, 4], [3, 4, 5]]
region_range = 1
first_run = True
increment = True
embedding_list_2_start = 0
embedding_list_2_end = len(embedding_list_1)
while region_range >= 0:
if first_run:
print('Cutting embedding list 1 from:', len(embedding_list_1)-region_range, 'to', len(embedding_list_1))
print(embedding_list_1[len(embedding_list_1)-region_range:])
print('Cutting embedding list 2 from:', 0, 'to', region_range)
embedding_list_2[:region_range]
region_range +=1
first_run = False
else:
chopped_off = embedding_list_1[len(embedding_list_1)-region_range:]
print(chopped_off)
embedding_list_2[embedding_list_2_start:region_range]
if increment:
region_range +=1
if region_range == len(embedding_list_1):
#break
#use full list
print(len(embedding_list_1))
embedding_list_2_start+=1
embedding_list_2_end+=1
print('Cutting embedding list 2 from', embedding_list_2_start, 'to', embedding_list_2_end)
print(embedding_list_2[embedding_list_2_start:embedding_list_2_end])
increment = False
if embedding_list_2_end == len(embedding_list_2):
#Stop incrementing end
#Start negative shift for other embedding
region_range-=1
print('Cutting embedding list 1 from: 0', 'to', region_range)
embedding_list_1[0:region_range]
embedding_list_2_start+=1
embedding_list_2_end+=1
print('cuting embedding list 2 from:', embedding_list_2_start, embedding_list_2_end)
embedding_list_2[:embedding_list_2_end]
这是一个快速但可能相当肮脏的尝试。
第一次迭代中的重叠看起来像这样:
让我们先看看与list2
相关的所有内容。在第一次迭代中
# Calculate the offset between the two lists
offset = 1 - len(list1) # -3
l2_window_start = offset
l2_window_end = 0
# The slice for list2 starts at the larger of 0 and l2_window_start
l2_start = max(0, l2_window_start)
# The slice for list2 ends at the smaller of 7 and l2_window_end
l2_end = min(len(list2) - 1, l2_window_end)
# Add one to l2_end because slices don't contain the end index.
list2_slice = list2[l2_start:l2_end+1]
现在,使用这些数字查看 list1
:
l1_window_start = -offset # starts off at 3
l1_start = max(0, l1_window_start)
# list1 slice needs to have as many elements as list2_slice
l1_end = l1_start + len(list2_slice)
list1_slice = list1[l1_start:l1_end]
随着迭代向前推进,l2_window_start
、l2_window_end
和offset
都增加了1。l1_window_start
减少了1。
将其放入循环中:
list1 = [7, 6, 9, 8]
list2 = [1, 2, 3, 4, 5, 3, 2, 1]
offset = l2_window_start = 1 - len(list1) # -3
l2_window_end = 0
l1_window_start = -offset
l1_window_end = len(list1) - 1
for iternum in range(11):
# The slice for list2 starts at the larger of 0 and l2_window_start
l2_start = max(0, l2_window_start)
# The slice for list2 ends at the smaller of 7 and l2_window_end
l2_end = min(len(list2) - 1, l2_window_end)
# Add one to l2_end because slices don't contain the end index.
list2_slice = list2[l2_start:l2_end+1]
l1_start = max(0, l1_window_start)
l1_end = l1_start + len(list2_slice)
list1_slice = list1[l1_start:l1_end]
print(iternum+1, list1_slice, list2_slice)
l1_window_start -= 1;
l2_window_start += 1; l2_window_end += 1; offset += 1
这给了我们所需的输出:
1 [8] [1]
2 [9, 8] [1, 2]
3 [6, 9, 8] [1, 2, 3]
4 [7, 6, 9, 8] [1, 2, 3, 4]
5 [7, 6, 9, 8] [2, 3, 4, 5]
6 [7, 6, 9, 8] [3, 4, 5, 3]
7 [7, 6, 9, 8] [4, 5, 3, 2]
8 [7, 6, 9, 8] [5, 3, 2, 1]
9 [7, 6, 9] [3, 2, 1]
10 [7, 6] [2, 1]
11 [7] [1]
我的解决方案与@pranav-hosangadi 的回答非常相似(也许最终相同)。我的结果略有不同,因为我的答案是根据每个列表中的窗口元素配对生成元组。
与@pranav-hosangadi 的回答一样,我们从涵盖整张幻灯片的范围开始。棘手的部分(至少对我而言)是制定正确的开始和结束。
a = [7, 6, 9, 8]
b = [1, 2, 3, 4, 5, 3, 2, 1]
a_len = len(a)
b_len = len(b)
for i in range(0, a_len + b_len -1):
a_start = max(0, a_len -i -1)
a_end = min(a_len, a_len + b_len - i)
b_start = max(0, i + 1 - a_len)
b_end = min(i + 1, b_len)
result = [(a[x], b[y]) for (x, y) in zip(range(a_start, a_end), range(b_start, b_end))]
print(result)
这会产生略有不同(错误?)的输出:
[(8, 1)]
[(9, 1), (8, 2)]
[(6, 1), (9, 2), (8, 3)]
[(7, 1), (6, 2), (9, 3), (8, 4)]
[(7, 2), (6, 3), (9, 4), (8, 5)]
[(7, 3), (6, 4), (9, 5), (8, 3)]
[(7, 4), (6, 5), (9, 3), (8, 2)]
[(7, 5), (6, 3), (9, 2), (8, 1)]
[(7, 3), (6, 2), (9, 1)]
[(7, 2), (6, 1)]
[(7, 1)]
这里是使用 zip 函数的一个稍微不同的变体;
l1 = [7, 6, 9, 8]
l2 = [1, 2, 3, 4, 5, 3, 2, 1]
def slide(la, lb):
lxa = []
lxa = [x for x in range(len(la))]
lxa.extend([None]* (len(lb) - 1))
lxb = [None] * (len(la) -1)
lxb.extend([x for x in range(len(lb))])
lxcnt = 0
rslt = []
while lxcnt < len(lxa):
tmp = []
matchs = zip(lxa, lxb)
for mtch in matchs:
if mtch[0] != None and mtch[1] != None:
tmp.append(mtch)
if tmp:
rslt.append(tmp)
lxa.insert(0, None)
lxa = lxa[:-1]
lxcnt += 1
return rslt
运行 slide(l1, l2)
,产量:
[[(3, 0)],
[(2, 0), (3, 1)],
[(1, 0), (2, 1), (3, 2)],
[(0, 0), (1, 1), (2, 2), (3, 3)],
[(0, 1), (1, 2), (2, 3), (3, 4)],
[(0, 2), (1, 3), (2, 4), (3, 5)],
[(0, 3), (1, 4), (2, 5), (3, 6)],
[(0, 4), (1, 5), (2, 6), (3, 7)],
[(0, 5), (1, 6), (2, 7)],
[(0, 6), (1, 7)],
[(0, 7)]]