将一个三维的numpy数组分割成3x3的网格。

3
我有一个三维的numpy数组,我想将它分割成3x3的网格。在numpy中是否有可用的函数实现呢?
假设我有如下形状为(9, 9, 3)的三维数组:
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],
        [ 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, 100, 101],
        [102, 103, 104],
        [105, 106, 107]],

       [[108, 109, 110],
        [111, 112, 113],
        [114, 115, 116],
        [117, 118, 119],
        [120, 121, 122],
        [123, 124, 125],
        [126, 127, 128],
        [129, 130, 131],
        [132, 133, 134]],

       [[135, 136, 137],
        [138, 139, 140],
        [141, 142, 143],
        [144, 145, 146],
        [147, 148, 149],
        [150, 151, 152],
        [153, 154, 155],
        [156, 157, 158],
        [159, 160, 161]],

       [[162, 163, 164],
        [165, 166, 167],
        [168, 169, 170],
        [171, 172, 173],
        [174, 175, 176],
        [177, 178, 179],
        [180, 181, 182],
        [183, 184, 185],
        [186, 187, 188]],

       [[189, 190, 191],
        [192, 193, 194],
        [195, 196, 197],
        [198, 199, 200],
        [201, 202, 203],
        [204, 205, 206],
        [207, 208, 209],
        [210, 211, 212],
        [213, 214, 215]],

       [[216, 217, 218],
        [219, 220, 221],
        [222, 223, 224],
        [225, 226, 227],
        [228, 229, 230],
        [231, 232, 233],
        [234, 235, 236],
        [237, 238, 239],
        [240, 241, 242]]])

我希望将其分成9个3x3网格,每个网格的形状为(3,3,3)。

以下是其中的前3个网格。

array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[27, 28, 29],
        [30, 31, 32],
        [33, 34, 35]],

       [[54, 55, 56],
        [57, 58, 59],
        [60, 61, 62]]])

array([[[9, 10, 11 ],
        [36, 37, 38 ],
        [63, 64, 65 ]],

       [[12, 13, 14 ],
        [39, 40, 41],
        [66, 67, 68]],

       [[15, 16, 17],
        [42, 43, 44],
        [69, 70, 71]]])

array([[[18, 19, 20],
        [45, 46, 47],
        [72, 73, 74]],

       [[21, 22, 23],
        [48, 49, 50],
        [75, 76, 77]],

       [[24, 25, 26],
        [51, 52, 53],
        [78, 79, 80]]])

2D中的分割逻辑是:
R1C1 | R1C2 | R1C3| R1C4 | R1C5 | R1C6 | R1C7 | R1C8 | R1C9 |
R2C1 | R2C2 | R2C3| R2C4 | R2C5 | R2C6 | R2C7 | R2C8 | R2C9 |
R3C1 | R3C2 | R3C3| R3C4 | R3C5 | R3C6 | R3C7 | R3C8 | R3C9 |
R4C1 | R4C2 | R4C3| R4C4 | R4C5 | R4C6 | R4C7 | R4C8 | R4C9 |
R5C1 | R5C2 | R5C3| R5C4 | R5C5 | R5C6 | R5C7 | R5C8 | R5C9 |
R6C1 | R6C2 | R6C3| R6C4 | R6C5 | R6C6 | R6C7 | R6C8 | R6C9 |
R7C1 | R7C2 | R7C3| R7C4 | R7C5 | R7C6 | R7C7 | R7C8 | R7C9 |
R8C1 | R8C2 | R8C3| R8C4 | R8C5 | R8C6 | R8C7 | R8C8 | R8C9 |
R9C1 | R9C2 | R9C3| R9C4 | R9C5 | R9C6 | R9C7 | R9C8 | R9C9 |

我希望以下九宫格能够呈现出来。
R1C1 | R1C2 | R1C3|
R2C1 | R2C2 | R2C3|
R3C1 | R3C2 | R3C3|

R1C4 | R1C5 | R1C6 |
R2C4 | R2C5 | R2C6 |
R3C4 | R3C5 | R3C6 |

R1C7 | R1C8 | R1C9 |
R2C7 | R2C8 | R2C9 |
R3C7 | R3C8 | R3C9 |

R4C1 | R4C2 | R4C3|
R5C1 | R5C2 | R5C3|
R6C1 | R6C2 | R6C3|

R4C4 | R4C5 | R4C6 |
R5C4 | R5C5 | R5C6 |
R6C4 | R6C5 | R6C6 |

 R4C7 | R4C8 | R4C9 |
 R5C7 | R5C8 | R5C9 |
 R6C7 | R6C8 | R6C9 |

R7C1 | R7C2 | R7C3|
R8C1 | R8C2 | R8C3|
R9C1 | R9C2 | R9C3|

R7C4 | R7C5 | R7C6 |
R8C4 | R8C5 | R8C6 |
R9C4 | R9C5 | R9C6 |

R7C7 | R7C8 | R7C9 |
R8C7 | R8C8 | R8C9 |
R9C7 | R9C8 | R9C9 |

到目前为止,我找到的唯一函数是split。但它只能将数组分割成子数组而不是网格。我必须遍历结果并再次调用split函数,同时加上axis=1参数。

1
请提供更具体的信息。您所说的3x3网格是什么意思?您的3D数组的尺寸是多少? - tiago
有许多不同的方法可以将一个 9x9x3 数组转换为 9 个 3x3x3 数组。由于您的 array 完全由 1 组成,无法确定您想要哪种排列方式。如果您的数组实际上是 np.arange(9*9*3).reshape(9,9,3),您希望看到什么输出? - DSM
@tiago和DSM,我已经编辑了问题以添加更多细节。 - Sudar
1个回答

6

如果您的数组arr的形状为(a,b,c),且a = aa*aaab = bb*bbb,则可以按以下方式创建形状为(aaa,bbb,C)a*b个元素的列表:

a, b, c = 9, 9, 3
aaa, bbb = 3, 3
arr = np.arange(a*b*c).reshape(a, b, c)

arr_view = arr.reshape(a//aaa, aaa, b//bbb, bbb, c)

如果您想要原始数组的副本,只需执行以下操作:
arr_grid = np.swapaxes(arr_view, 1, 2).reshape(-1, aaa, bbb, c)

如果你想要一个数组的视图列表,可能有更好的方法,但这个方法应该可以工作:
arr_view = np.swapaxes(arr_view, 1, 2)
arr_grid = [arr_view[j] for j in zip(*np.unravel_index(np.arange(a*b//aaa//bbb),
                                                       (a//aaa, b//bbb)))]

当我执行最后一行时,我会得到以下错误 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: arange: scalar arguments expected instead of a tuple. - Sudar
暂时无法测试,但是我觉得可能是缺少了一个括号,现在应该可以正常工作了。 - Jaime
我也注意到了括号缺失的问题。我发布的错误消息是在括号缺失后出现的。 - Sudar
试试我的修改,缺失的括号不应该放在结尾,而是放在我添加的地方,即在 a*b//aaa//bbb 之后。 - Jaime

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接