简体   繁体   English

从Numpy 3D阵列转换为2D阵列

[英]Conversion from a Numpy 3D array to a 2D array

Having the following 3D array (9,9,9): 拥有以下3D阵列(9,9,9):

>>> np.arange(729).reshape((9,9,9))
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]]
      ...
       [[648 649 650 651 652 653 654 655 656]
        [657 658 659 660 661 662 663 664 665]
        [666 667 668 669 670 671 672 673 674]
        [675 676 677 678 679 680 681 682 683]
        [684 685 686 687 688 689 690 691 692]
        [693 694 695 696 697 698 699 700 701]
        [702 703 704 705 706 707 708 709 710]
        [711 712 713 714 715 716 717 718 719]
        [720 721 722 723 724 725 726 727 728]]])

How do I reshape it to look like this 2D array (27,27): 我如何重塑它看起来像这个二维数组(27,27):

在此输入图像描述

You need to go 6D with one reshaping basically splitting each axes into two, then transpose to push back the even axes (2nd, 4th and 6th) to the end and a final reshape back to 2D - 你需要通过一次整形来进行6D ,基本上将每个轴分成两个,然后转置以偶数轴(第2,第4和第6) 推回到结束,最后重塑回到2D -

a.reshape(-1,3,3,3,3,3).transpose(0,2,4,1,3,5).reshape(27,27)

Sample run - 样品运行 -

In [28]: a = np.arange(729).reshape((9,9,9))

In [29]: out = a.reshape(-1,3,3,3,3,3).transpose(0,2,4,1,3,5).reshape(27,27)

In [30]: out[0]
Out[30]: 
array([  0,   1,   2,   9,  10,  11,  18,  19,  20,  81,  82,  83,  90,
        91,  92,  99, 100, 101, 162, 163, 164, 171, 172, 173, 180, 181, 182])

In [31]: out[1]
Out[31]: 
array([  3,   4,   5,  12,  13,  14,  21,  22,  23,  84,  85,  86,  93,
        94,  95, 102, 103, 104, 165, 166, 167, 174, 175, 176, 183, 184, 185])

In [32]: out[2]
Out[32]: 
array([  6,   7,   8,  15,  16,  17,  24,  25,  26,  87,  88,  89,  96,
        97,  98, 105, 106, 107, 168, 169, 170, 177, 178, 179, 186, 187, 188])

In [33]: out[3]
Out[33]: 
array([ 27,  28,  29,  36,  37,  38,  45,  46,  47, 108, 109, 110, 117,
       118, 119, 126, 127, 128, 189, 190, 191, 198, 199, 200, 207, 208, 209])

In [34]: out[-1]
Out[34]: 
array([546, 547, 548, 555, 556, 557, 564, 565, 566, 627, 628, 629, 636,
       637, 638, 645, 646, 647, 708, 709, 710, 717, 718, 719, 726, 727, 728])

Generic case solution 通用案例解决方案

BSZ = [3,3] # Block size
p,q = BSZ
out = a.reshape(p,q,p,q,p,q).transpose(0,2,4,1,3,5).reshape(p**3,q**3)

Divide and Conquer is very applicable to such problem. 分而治之非常适用于这样的问题。 It's easier to understand compared with numpy magic. 与numpy魔术相比,它更容易理解。 And this can solve not only 27 * 27 problem, also all 3 power problems such as case of 81 * 81 . 这不仅可以解决27 * 27问题,还可以解决所有3个电源问题,如81 * 81的情况。 Show the code first. 首先显示代码。

import numpy as np

# np.arange(729).reshape((9,9,9)).flatten()
arr = np.arange(729)

result =  np.empty((27,27))

def assign(width, start, end, anchor_x, anchor_y):
    if width > 3:
        sub_width = width / 3
        for i in range(3):
            for j in range(3):
                assign(
                    sub_width,
                    start + (i * 3 + j) * sub_width ** 2,
                    start + (i * 3 + j) * sub_width ** 2 + sub_width ** 2,
                    anchor_x + i * sub_width,
                    anchor_y + j * sub_width)

    else:
        result[anchor_x:anchor_x+3, anchor_y:anchor_y+3] = arr[start:end].reshape(3,3)

assign(27, 0, 729, 0, 0)

print(result)

Explanation: 说明:

Every time you divide a big n*n matrix to 9 smaller (n/3) * (n/3) matrix, and solve them each recursively. 每次将一个大的n * n矩阵划分为9个较小的(n / 3)*(n / 3)矩阵,并逐个求解它们。 Until width of matrix equals to 3, stop recursion and copy 9 numbers ( arr[start:end] ) to result[anchor_x:anchor_x+3, anchor_y:anchor_y+3] 直到矩阵的宽度等于3,停止递归并复制9个数字( arr[start:end] )到result[anchor_x:anchor_x+3, anchor_y:anchor_y+3]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM