如何洗牌隐式对数组?

How to shuffle array of implicit pairs?

我正在尝试对一组图像进行洗牌,这对我来说有点棘手。

示例: 我有 20 个图像序列,每个序列包含 1000 帧 .. 它们保存在一个数组中 .. 所以我们假设,数组看起来像这样

[[1_1],[1_2],[1_3],[1_4],[1_5],[1_6],[2_1],[2_2],[2_3],[2_4],[2_5],[2_6],[3_1],[3_2],[3_3],[3_4],[3_5],[3_6]]

等等,这只是 3 个序列的最小示例,每个序列有 6 个帧..但我最终想要实现的是顺序帧的混洗,所以类似的东西

[[1_4],[1_5],[2_3],[2_4],[3_5],[3_6],[1_3],[1_4],[1_1],[1_2],[3_2],[3_3],[1_2],[1_3],[3_3],[3_4],[2_1],[2_2] ....]

像这样的东西很简单..所以我想产生一个洗牌,但不是单个元素,而是每个元素和下一个元素,即我想洗牌成对。

有办法吗?

我正在开发一个更简洁的嵌套列表(不信任 [1_1]):

L = [['1_1'],['1_2'],['1_3'],['1_4'],['1_5'],['1_6'],['2_1'],['2_2'],['2_3'],['2_4'],['2_5'],['2_6'],['3_1'],['3_2'],['3_3'],['3_4'],['3_5'],['3_6']]

然后我创建一个嵌套列表,即一个对列表,具有理解:

S=[[L[z*2+y] for y in range(2)] for z in range(len(L)//2)] # version 1
S=[[L[z+y] for y in range(2)] for z in range(len(L)-1)]    # version 2
S

请注意,有 length/2 个非重叠对, 但 N-1 对重叠(每个条目一对,最后一个除外)。

请注意,在下面的所有输出中,我都手动添加了换行符以提高可读性 和清晰的目的。

此时输出为:

版本 1,非重叠对:

[[['1_1'], ['1_2']], 
 [['1_3'], ['1_4']],
 [['1_5'], ['1_6']], 
 [['2_1'], ['2_2']],
 [['2_3'], ['2_4']],
 [['2_5'], ['2_6']],
 [['3_1'], ['3_2']],
 [['3_3'], ['3_4']],
 [['3_5'], ['3_6']]]

版本 2,重叠对:

[[['1_1'], ['1_2']],
 [['1_2'], ['1_3']],
 [['1_3'], ['1_4']],
 [['1_4'], ['1_5']],
 [['1_5'], ['1_6']],
 [['1_6'], ['2_1']],
 [['2_1'], ['2_2']],
 [['2_2'], ['2_3']],
 [['2_3'], ['2_4']],
 [['2_4'], ['2_5']],
 [['2_5'], ['2_6']],
 [['2_6'], ['3_1']],
 [['3_1'], ['3_2']],
 [['3_2'], ['3_3']],
 [['3_3'], ['3_4']],
 [['3_4'], ['3_5']],
 [['3_5'], ['3_6']]]

然后对S进行洗牌,只会对S内的pair进行洗牌,不会对pairs内的pairs进行洗牌,这就是先制作pairs列表的意义

import random
random.shuffle(S)
S

此时输出,当然还是嵌套:

非重叠随机对:

[[['3_3'], ['3_4']],
 [['3_1'], ['3_2']],
 [['2_3'], ['2_4']],
 [['3_5'], ['3_6']],
 [['1_1'], ['1_2']],
 [['1_3'], ['1_4']],
 [['2_1'], ['2_2']],
 [['1_5'], ['1_6']],
 [['2_5'], ['2_6']]]

输出重叠随机对:

[[['1_2'], ['1_3']],
 [['2_1'], ['2_2']],
 [['2_4'], ['2_5']],
 [['2_2'], ['2_3']],
 [['1_3'], ['1_4']],
 [['3_4'], ['3_5']],
 [['3_3'], ['3_4']],
 [['3_2'], ['3_3']],
 [['1_6'], ['2_1']],
 [['2_5'], ['2_6']],
 [['2_6'], ['3_1']],
 [['1_4'], ['1_5']],
 [['1_1'], ['1_2']],
 [['2_3'], ['2_4']],
 [['1_5'], ['1_6']],
 [['3_1'], ['3_2']],
 [['3_5'], ['3_6']]]

也许您可以将其用于项目的其余部分。
如果不解散对

L2=[]
for x in S:
  for y in x:
    L2.append(y)
print(L2)

输出溶解的非重叠对:

[['3_3'], ['3_4'], ['3_1'], ['3_2'], ['2_3'], ['2_4'],
 ['3_5'], ['3_6'], ['1_1'], ['1_2'], ['1_3'], ['1_4'],
 ['2_1'], ['2_2'], ['1_5'], ['1_6'], ['2_5'], ['2_6']]

输出溶解的重叠对:

[['1_2'], ['1_3'], ['2_1'], ['2_2'], ['2_4'], ['2_5'],
 ['2_2'], ['2_3'], ['1_3'], ['1_4'], ['3_4'], ['3_5'],
 ['3_3'], ['3_4'], ['3_2'], ['3_3'], ['1_6'], ['2_1'],
 ['2_5'], ['2_6'], ['2_6'], ['3_1'], ['1_4'], ['1_5'],
 ['1_1'], ['1_2'], ['2_3'], ['2_4'], ['1_5'], ['1_6'],
 ['3_1'], ['3_2'], ['3_5'], ['3_6']]

我们需要一些导入来简化事情:

from functools import reduce
from itertools import groupby
import operator
import random

假设你有一个像这样的列表:

ar = [['1_1'],['1_2'],['1_3'],['1_4'],['1_5'],['1_6'],['2_1'],['2_2'],['2_3'],['2_4'],['2_5'],['2_6'],['3_1'],['3_2'],['3_3'],['3_4'],['3_5'],['3_6']]

我们可以先按图片将它们分组,这样我们就只生成有效的对:

groupedbyimage = [list(g[1]) for g in groupby(ar, lambda x: x[0][0])]

以上 lambda 在你的情况下必须是其他东西,以便在不只是比较嵌套列表中字符串的第一个字母时生成找到正确的组。

接下来我们可以压缩图像列表,它们自己移动一位:

groupedandpaired = [list(zip(x, x[1:])) for x in groupedbyimage]

我们现在可以将 groupedandpaired 列表展平为 pairlist:

pairlist = reduce(operator.concat, groupedandpaired)

现在我们只需打乱成对列表,然后再次将其展平以获得所需的结果:

random.shuffle(pairlist)
result = list(reduce(operator.concat, pairlist))

然后在 REPL 中打印结果,我们会看到如下内容:

>>> result
[['1_5'], ['1_6'], ['2_1'], ['2_2'], ['1_1'], ['1_2'], ['3_2'], 
 ['3_3'], ['2_2'], ['2_3'], ['3_5'], ['3_6'], ['3_1'], ['3_2'], 
 ['1_3'], ['1_4'], ['1_4'], ['1_5'], ['3_4'], ['3_5'], ['3_3'], 
 ['3_4'], ['2_5'], ['2_6'], ['2_3'], ['2_4'], ['1_2'], ['1_3'], 
 ['2_4'], ['2_5']]