python - 如何在 numpy 数组中随机洗牌 "tiles"

标签 python python-3.x numpy shuffle

我有一个 nxn numpy 数组,我想将它平均分成 nxn block 并随机打乱这些 block ,同时保留 block 内的图案。

例如,如果我有一个大小为 (200,200) 的数组,我希望能够将其分成 16 个大小为 (50,50) 的数组,或者甚至是 64 个大小为 (25,25) 的数组,并且随机打乱这些,同时保留原始数组 (200,200) 的相同形状并保留较小数组内的数字顺序。

我查找了特定的 numpy 函数,找到了 numpy.random.shuffle(x) 函数,但这会随机打乱数组的各个元素。我只想在较大的数组中随机排列这些较小的数组。

是否有任何 numpy 函数或快速方法可以做到这一点?我不确定从哪里开始。

编辑:进一步明确我想要什么:

假设我有一个形状为 (10,10) 值的输入二维数组:

0   1   2   3   4   5   6   7   8   9
10  11  12  13  14  15  16  17  18  19
20  21  22  23  24  25  26  27  28  29
30  31  32  33  34  35  36  37  38  39
40  41  42  43  44  45  46  47  48  49
50  51  52  53  54  55  56  57  58  59
60  61  62  63  64  65  66  67  68  69
70  71  72  73  74  75  76  77  78  79
80  81  82  83  84  85  86  87  88  89
90  91  92  93  94  95  96  97  98  99

我选择的图 block 大小使其均匀地适合此数组,因此由于此数组的形状为 (10,10),我可以选择将其拆分为 4 (5,5) 个图 block ,或 25 (2, 2)瓷砖。因此,如果我选择 4 (5,5) 个图 block ,我想随机打乱这些图 block ,从而生成如下所示的输出数组:

50  51  52  53  54  0   1   2   3   4
60  61  62  63  64  10  11  12  13  14
70  71  72  73  74  20  21  22  23  24
80  81  82  83  84  30  31  32  33  34
90  91  92  93  94  40  41  42  43  44
55  56  57  58  59  5   6   7   8   9
65  66  67  68  69  15  16  17  18  19
75  76  77  78  79  25  26  27  28  29
85  86  87  88  89  35  36  37  38  39
95  96  97  98  99  45  46  47  48  49

每个数组(输入数组、输出数组和单独的图 block )都是正方形,因此当随机打乱时,主数组的大小和维度保持不变 (10,10)。

最佳答案

这是我使用循环的解决方案

import numpy as np

arr = np.arange(36).reshape(6,6)

def suffle_section(arr, n_sections):

    assert arr.shape[0]==arr.shape[1], "arr must be square"
    assert arr.shape[0]%n_sections == 0, "arr size must divideable into equal n_sections"

    size = arr.shape[0]//n_sections


    new_arr = np.empty_like(arr)
    ## randomize section's row index

    rand_indxes = np.random.permutation(n_sections*n_sections)

    for i in range(n_sections):
        ## randomize section's column index
        for j in  range(n_sections):

            rand_i = rand_indxes[i*n_sections + j]//n_sections
            rand_j = rand_indxes[i*n_sections + j]%n_sections

            new_arr[i*size:(i+1)*size, j*size:(j+1)*size] = \
                arr[rand_i*size:(rand_i+1)*size, rand_j*size:(rand_j+1)*size]

    return new_arr


result = suffle_section(arr, 3)


display(arr)
display(result)

array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23],
       [24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35]])

array([[ 4,  5, 16, 17, 24, 25],
       [10, 11, 22, 23, 30, 31],
       [14, 15,  2,  3,  0,  1],
       [20, 21,  8,  9,  6,  7],
       [26, 27, 12, 13, 28, 29],
       [32, 33, 18, 19, 34, 35]])

关于python - 如何在 numpy 数组中随机洗牌 "tiles",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58029768/

相关文章:

python-3.x - 无法使用类对象中的ssh隧道建立与远程mongoDB服务器的连接

python - 类型错误 : unsupported operand type(s) for +: 'float' and 'str'

python - NumPy 数组的就地类型转换

python - 如何在 python 中使用 action=fetch 向 url 发送 HTTP POST 请求?

python - 如何按用户定义的顺序对列表中的列表进行排序?

python - 重命名组名标题 pandas

python - 如何使用 ndarray 参数和/或输出定义 numba 类?

python - 如何在打印前让单个字符串的行 sleep ?

python - 如何在 Peewee 中创建一个将其值转换为 MD5 的字段

python - Numpy 矩阵行比较