While implementing a Kronecker-product
for pedagogical reasons (without using the obvious and readily available np.kron()
), I obtained a 4 dimensional array as an intermediate result, which I've to reshape to get the final result.
在出于教学原因实现Kronecker-product时(不使用明显且现成的np.kron())),我获得了一个4维数组作为中间结果,我必须对其进行重新组合才能得到最终结果。
But, I still can't wrap my head around reshaping these high dimensional arrays. I have this 4D
array:
但是,我仍然不能把我的头脑集中在重塑这些高维数组上。我有这个4D数组
array([[[[ 0, 0],
[ 0, 0]],
[[ 5, 10],
[15, 20]]],
[[[ 6, 12],
[18, 24]],
[[ 7, 14],
[21, 28]]]])
This is of shape (2, 2, 2, 2)
and I'd like to reshape it to (4,4)
. One might think that this is obvious to do with
这是形状为(2,2,2,2,2,2)我想把它重塑为(4,4)有人可能会认为这显然与此有关
np.reshape(my4darr, (4,4))
But, the above reshape does not give me the expected result which is:
但是,上面的重塑并没有给我预期的结果,即:
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
As you can see, all the elements in the expected result are present in the 4D
array. I just can't get the hang of doing the reshape correctly as needed. In addition to the answer, some explanation of how to do the reshape
for such high dimensional arrays would be really helpful. Thanks!
如您所见,预期结果中的所有元素都显示在4D数组中。我只是不知道如何在需要的时候正确地进行重塑。除了答案之外,对如何为这样的高维数组进行重新设计进行一些解释将会非常有帮助。谢谢!
2 个解决方案
#1
20
General idea for nd
to nd
transformation
The idea with such nd
to nd
transformation is using just two things - Permute axes (with numpy.transpose
or numpy.rollaxis
if the needed permute order is a rolled one or numpy.swapaxes
if just two axes need to be swapped) and Reshape.
这种nd到nd转换的想法是使用两个东西——置换轴(使用numpy)。置或numpy。如果需要的排列顺序是滚动的或者是numpy,那么可以使用rollaxis。如果只需要交换两个轴,则交换swapaxes并重新组合。
Permute axes : To get the order such that the flattened version corresponds to the flattened version of output. So, if you somehow end up using it twice, look again because you shouldn't.
排列坐标轴:为了获得使变平版本对应于输出的变平版本的顺序。所以,如果你最终用了两次,再看一次,因为你不应该这样做。
Reshape : To split the axes or bring the final output to the desired shape. Splitting axes is needed mostly at the start, when the input is of lower-dim and we are needed to split into blocks. Again, you shouldn't need this more than twice.
重形:将轴分开或将最终输出带至所需的形状。在开始时需要分割轴,当输入是低暗的,我们需要分割成块。同样,你不应该需要超过两次。
Hence, generally we would have three steps :
因此,我们通常有三个步骤:
[ Reshape ] ---> [ Permute axes ] ---> [ Reshape ]
Create more axes Bring axes Merge axes
into correct order
Back-tracking method
回溯法
The safest way to solve, given the input and output is through, what one could call as the back-tracking method, i.e. split the axes of the input (when going from smaller nd
to bigger nd
) or split the axes of the output (when going from bigger nd
to smaller nd
). The idea with the splitting is to bring the number of dims of the smaller nd
one same as the bigger nd
one. Then, study the strides of the output and match it up against the input to get the required permute order. Finally, a reshape (default way or C order) might be needed at the end, if the final one is a smaller nd
one, to merge axes.
考虑到输入和输出,最安全的解决方法是通过所谓的反向跟踪方法,即分割输入轴(从较小的nd到较大的nd)或分割输出轴(从较大的nd到较小的nd)。分裂的想法是把较小的和较大的一样的dims的数目。然后,研究输出的步长,并将其与输入匹配,得到所需的排列顺序。最后,如果最后一个是较小的nd,那么在最后可能需要一个整形(默认方式或C阶)来合并坐标轴。
If both input and output are of same number of dims, then we would need to split both and break into blocks and study their strides against each other. In such cases, we should have the additional input parameter of block sizes, but that's probably off-topic.
如果输入和输出都是相同数量的dims,那么我们就需要将两者分开,然后分解成块,然后研究它们之间的距离。在这种情况下,我们应该有块大小的额外输入参数,但这可能是离题的。
Example
Let's use this specific case to demonstrate how to apply those strategies. In here, the input is 4D
, while output is 2D
. So, most probably, we won't need reshape to split. So, we need to start with permuting axes. Since, the final output is not 4D
, but a 2D
one, we would need a reshape at the end.
让我们用这个具体的例子来演示如何应用这些策略。在这里输入是4D,而输出是2D。因此,最可能的情况是,我们不需要重新设计来进行拆分。我们需要从排列坐标轴开始。由于最终输出不是4D,而是2D,所以我们需要在最后进行重新设计。
Now, the input here is :
这里的输入是:
In [270]: a
Out[270]:
array([[[[ 0, 0],
[ 0, 0]],
[[ 5, 10],
[15, 20]]],
[[[ 6, 12],
[18, 24]],
[[ 7, 14],
[21, 28]]]])
The expected output is :
预期产出为:
In [271]: out
Out[271]:
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
Also, this is a bigger nd
to smaller nd
transformation, so the back-tracking method would involve, splitting the output and studying its strides and matching up against the corresponding values in input :
同时,这是一个更大的nd到更小的nd转换,因此回溯方法将涉及到,分割输出,研究其步幅,并与输入的对应值匹配:
axis = 3
--- -->
axis = 1
------>
axis=2| axis=0| [ 0, 5, 0, 10],
| [ 6, 7, 12, 14],
v
| [ 0, 15, 0, 20],
v
[18, 21, 24, 28]])
Hence, the permuted order needed is (2,0,3,1)
:
因此,所需的排列顺序为(2,0,3,1):
In [275]: a.transpose((2, 0, 3, 1))
Out[275]:
array([[[[ 0, 5],
[ 0, 10]],
[[ 6, 7],
[12, 14]]],
[[[ 0, 15],
[ 0, 20]],
[[18, 21],
[24, 28]]]])
Then, simply reshape to the expected shape :
然后,简单地重塑到预期的形状:
In [276]: a.transpose((2, 0, 3, 1)).reshape(4,4)
Out[276]:
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
More examples
更多的例子
I dug up my history and found few Q&As
based on nd
to nd
transformations. These could serve as other example cases, albeit with lesser explanation (mostly). As mentioned earlier, at most two reshapes
and at most one swapaxes
/transpose
did the job everywhere. They are listed below :
我挖掘了我的历史,发现很少有Q&As基于nd和nd的转换。这些可以作为其他的例子,尽管有较少的解释(主要是)。正如前面所提到的,在大多数情况下,两个重构和最多一个swapax /转置都可以完成所有的工作。以下列出:
- Python Reshape 3d array into 2d
- Python将3d数组重新格式化为2d
- reshape an array using python/numpy
- 使用python/numpy重新定义数组
- Merging non-overlapping array blocks
- 数组合并重叠块
- Conversion from a Numpy 3D array to a 2D array
- 从Numpy 3D数组转换为2D数组
- how to reshape an N length vector to a 3x(N/3) matrix in numpy using reshape
- 如何用重新塑造法将一个N长度的向量在numpy中重新塑造成一个3x(N/3)矩阵
- Construct image from 4D list
- 从4D列表中构造图像
- Reshaping/Combining several sub-matrices to one matrix in multi-dimensional space
- 在多维空间中,将多个子矩阵变换成一个矩阵。
- Interlace various small 2D matrices into a bigger one
- 将各种小的二维矩阵拼接成一个较大的矩阵
- how to retrieve every section by 3X3?
- 如何用3X3来检索每一部分?
- Reshaping 3D Numpy Array to a 2D array
- 将3D Numpy数组重新定义为2D数组
- Iterate in submatrices through a bigger matrix
- 在一个更大的矩阵中迭代子矩阵
- Reorganizing a 2D numpy array into 3D
- 将2D numpy数组重新组织为3D
- Numpy change shape from (3, 512, 660, 4) to (3,2048,660,1)
- 从(3,512,660,4)到(3,2048,660,1)的Numpy变化形状
- Numpy: rotate sub matrix m of M
- Numpy:旋转子矩阵m (m)
- Split a 3D numpy array into 3D blocks
- 将一个3D数字数组分割成3D块
- Converting 3D matrix to cascaded 2D Matrices
- 将三维矩阵转换为级联二维矩阵
- Rearranging numpy array
- 重新安排numpy数组
- Numpy: Reshape array along a specified axis
- Numpy:沿着指定的轴重塑数组
- How to construct 2d array from 2d arrays
- 如何从二维数组构造二维数组
- How to form a matrix from submatrices?
- 如何从子矩阵生成矩阵?
- Python: Reshape 3D image series to pixel series
- Python:将3D图像系列重新塑造成像素系列
#2
9
It seems like you're looking for a transpose
followed by a reshape
.
看起来你在寻找一个转置然后是一个整形。
x.transpose((2, 0, 3, 1)).reshape(np.prod(x.shape[:2]), -1)
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
To help you understand why a transposition is needed, let's analyse your incorrectly shaped output (obtained by a single reshape
call) to understand why it is incorrect.
为了帮助您理解为什么需要换位,让我们分析您不正确的形状输出(通过一次重新配置调用获得),以理解它为什么不正确。
A simple 2D reshaped version of this result (without any transposition) looks like this -
这个结果的一个简单的2D重构版本(没有任何换位)看起来像这样
x.reshape(4, 4)
array([[ 0, 0, 0, 0],
[ 5, 10, 15, 20],
[ 6, 12, 18, 24],
[ 7, 14, 21, 28]])
Now consider this output with respect to your expected output -
现在考虑这个输出与您期望的输出-。
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
You'll notice that your actual result is obtained by a Z-like traversal of your incorrectly shaped output -
您将注意到,您的实际结果是通过类似z的遍历错误形状的输出-获得的
start
| /| /| /|
|/ | / |/ |
/ / /
/ / /
| /| / | /|
|/ |/ |/ |
end
This implies that you must move over the array in varying strides to get your actual result. In conclusion, a simple reshape is not enough. You must transpose the original array, in such a manner that these Z-like elements are made to be contiguous to each other, such that a subsequent reshape call gives you the output you need.
这意味着您必须在不同的步骤中移动数组以获得实际的结果。总之,简单的改造是不够的。您必须对原始数组进行转置,以使这些类z的元素彼此相邻,以便后续的重新配置调用能够提供您所需的输出。
To understand how to transpose correctly, you should trace the elements along the input and figure out what axes you need to jump to get to each one in the output. The transposition follows accordingly. Divakar's answer does a sterling job of explaining this.
要理解如何正确地进行转置,您应该沿着输入跟踪元素,并找出需要跳转到输出中的每个坐标轴。接下来的换位。迪瓦卡的回答很好地解释了这一点。
#1
20
General idea for nd
to nd
transformation
The idea with such nd
to nd
transformation is using just two things - Permute axes (with numpy.transpose
or numpy.rollaxis
if the needed permute order is a rolled one or numpy.swapaxes
if just two axes need to be swapped) and Reshape.
这种nd到nd转换的想法是使用两个东西——置换轴(使用numpy)。置或numpy。如果需要的排列顺序是滚动的或者是numpy,那么可以使用rollaxis。如果只需要交换两个轴,则交换swapaxes并重新组合。
Permute axes : To get the order such that the flattened version corresponds to the flattened version of output. So, if you somehow end up using it twice, look again because you shouldn't.
排列坐标轴:为了获得使变平版本对应于输出的变平版本的顺序。所以,如果你最终用了两次,再看一次,因为你不应该这样做。
Reshape : To split the axes or bring the final output to the desired shape. Splitting axes is needed mostly at the start, when the input is of lower-dim and we are needed to split into blocks. Again, you shouldn't need this more than twice.
重形:将轴分开或将最终输出带至所需的形状。在开始时需要分割轴,当输入是低暗的,我们需要分割成块。同样,你不应该需要超过两次。
Hence, generally we would have three steps :
因此,我们通常有三个步骤:
[ Reshape ] ---> [ Permute axes ] ---> [ Reshape ]
Create more axes Bring axes Merge axes
into correct order
Back-tracking method
回溯法
The safest way to solve, given the input and output is through, what one could call as the back-tracking method, i.e. split the axes of the input (when going from smaller nd
to bigger nd
) or split the axes of the output (when going from bigger nd
to smaller nd
). The idea with the splitting is to bring the number of dims of the smaller nd
one same as the bigger nd
one. Then, study the strides of the output and match it up against the input to get the required permute order. Finally, a reshape (default way or C order) might be needed at the end, if the final one is a smaller nd
one, to merge axes.
考虑到输入和输出,最安全的解决方法是通过所谓的反向跟踪方法,即分割输入轴(从较小的nd到较大的nd)或分割输出轴(从较大的nd到较小的nd)。分裂的想法是把较小的和较大的一样的dims的数目。然后,研究输出的步长,并将其与输入匹配,得到所需的排列顺序。最后,如果最后一个是较小的nd,那么在最后可能需要一个整形(默认方式或C阶)来合并坐标轴。
If both input and output are of same number of dims, then we would need to split both and break into blocks and study their strides against each other. In such cases, we should have the additional input parameter of block sizes, but that's probably off-topic.
如果输入和输出都是相同数量的dims,那么我们就需要将两者分开,然后分解成块,然后研究它们之间的距离。在这种情况下,我们应该有块大小的额外输入参数,但这可能是离题的。
Example
Let's use this specific case to demonstrate how to apply those strategies. In here, the input is 4D
, while output is 2D
. So, most probably, we won't need reshape to split. So, we need to start with permuting axes. Since, the final output is not 4D
, but a 2D
one, we would need a reshape at the end.
让我们用这个具体的例子来演示如何应用这些策略。在这里输入是4D,而输出是2D。因此,最可能的情况是,我们不需要重新设计来进行拆分。我们需要从排列坐标轴开始。由于最终输出不是4D,而是2D,所以我们需要在最后进行重新设计。
Now, the input here is :
这里的输入是:
In [270]: a
Out[270]:
array([[[[ 0, 0],
[ 0, 0]],
[[ 5, 10],
[15, 20]]],
[[[ 6, 12],
[18, 24]],
[[ 7, 14],
[21, 28]]]])
The expected output is :
预期产出为:
In [271]: out
Out[271]:
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
Also, this is a bigger nd
to smaller nd
transformation, so the back-tracking method would involve, splitting the output and studying its strides and matching up against the corresponding values in input :
同时,这是一个更大的nd到更小的nd转换,因此回溯方法将涉及到,分割输出,研究其步幅,并与输入的对应值匹配:
axis = 3
--- -->
axis = 1
------>
axis=2| axis=0| [ 0, 5, 0, 10],
| [ 6, 7, 12, 14],
v
| [ 0, 15, 0, 20],
v
[18, 21, 24, 28]])
Hence, the permuted order needed is (2,0,3,1)
:
因此,所需的排列顺序为(2,0,3,1):
In [275]: a.transpose((2, 0, 3, 1))
Out[275]:
array([[[[ 0, 5],
[ 0, 10]],
[[ 6, 7],
[12, 14]]],
[[[ 0, 15],
[ 0, 20]],
[[18, 21],
[24, 28]]]])
Then, simply reshape to the expected shape :
然后,简单地重塑到预期的形状:
In [276]: a.transpose((2, 0, 3, 1)).reshape(4,4)
Out[276]:
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
More examples
更多的例子
I dug up my history and found few Q&As
based on nd
to nd
transformations. These could serve as other example cases, albeit with lesser explanation (mostly). As mentioned earlier, at most two reshapes
and at most one swapaxes
/transpose
did the job everywhere. They are listed below :
我挖掘了我的历史,发现很少有Q&As基于nd和nd的转换。这些可以作为其他的例子,尽管有较少的解释(主要是)。正如前面所提到的,在大多数情况下,两个重构和最多一个swapax /转置都可以完成所有的工作。以下列出:
- Python Reshape 3d array into 2d
- Python将3d数组重新格式化为2d
- reshape an array using python/numpy
- 使用python/numpy重新定义数组
- Merging non-overlapping array blocks
- 数组合并重叠块
- Conversion from a Numpy 3D array to a 2D array
- 从Numpy 3D数组转换为2D数组
- how to reshape an N length vector to a 3x(N/3) matrix in numpy using reshape
- 如何用重新塑造法将一个N长度的向量在numpy中重新塑造成一个3x(N/3)矩阵
- Construct image from 4D list
- 从4D列表中构造图像
- Reshaping/Combining several sub-matrices to one matrix in multi-dimensional space
- 在多维空间中,将多个子矩阵变换成一个矩阵。
- Interlace various small 2D matrices into a bigger one
- 将各种小的二维矩阵拼接成一个较大的矩阵
- how to retrieve every section by 3X3?
- 如何用3X3来检索每一部分?
- Reshaping 3D Numpy Array to a 2D array
- 将3D Numpy数组重新定义为2D数组
- Iterate in submatrices through a bigger matrix
- 在一个更大的矩阵中迭代子矩阵
- Reorganizing a 2D numpy array into 3D
- 将2D numpy数组重新组织为3D
- Numpy change shape from (3, 512, 660, 4) to (3,2048,660,1)
- 从(3,512,660,4)到(3,2048,660,1)的Numpy变化形状
- Numpy: rotate sub matrix m of M
- Numpy:旋转子矩阵m (m)
- Split a 3D numpy array into 3D blocks
- 将一个3D数字数组分割成3D块
- Converting 3D matrix to cascaded 2D Matrices
- 将三维矩阵转换为级联二维矩阵
- Rearranging numpy array
- 重新安排numpy数组
- Numpy: Reshape array along a specified axis
- Numpy:沿着指定的轴重塑数组
- How to construct 2d array from 2d arrays
- 如何从二维数组构造二维数组
- How to form a matrix from submatrices?
- 如何从子矩阵生成矩阵?
- Python: Reshape 3D image series to pixel series
- Python:将3D图像系列重新塑造成像素系列
#2
9
It seems like you're looking for a transpose
followed by a reshape
.
看起来你在寻找一个转置然后是一个整形。
x.transpose((2, 0, 3, 1)).reshape(np.prod(x.shape[:2]), -1)
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
To help you understand why a transposition is needed, let's analyse your incorrectly shaped output (obtained by a single reshape
call) to understand why it is incorrect.
为了帮助您理解为什么需要换位,让我们分析您不正确的形状输出(通过一次重新配置调用获得),以理解它为什么不正确。
A simple 2D reshaped version of this result (without any transposition) looks like this -
这个结果的一个简单的2D重构版本(没有任何换位)看起来像这样
x.reshape(4, 4)
array([[ 0, 0, 0, 0],
[ 5, 10, 15, 20],
[ 6, 12, 18, 24],
[ 7, 14, 21, 28]])
Now consider this output with respect to your expected output -
现在考虑这个输出与您期望的输出-。
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
You'll notice that your actual result is obtained by a Z-like traversal of your incorrectly shaped output -
您将注意到,您的实际结果是通过类似z的遍历错误形状的输出-获得的
start
| /| /| /|
|/ | / |/ |
/ / /
/ / /
| /| / | /|
|/ |/ |/ |
end
This implies that you must move over the array in varying strides to get your actual result. In conclusion, a simple reshape is not enough. You must transpose the original array, in such a manner that these Z-like elements are made to be contiguous to each other, such that a subsequent reshape call gives you the output you need.
这意味着您必须在不同的步骤中移动数组以获得实际的结果。总之,简单的改造是不够的。您必须对原始数组进行转置,以使这些类z的元素彼此相邻,以便后续的重新配置调用能够提供您所需的输出。
To understand how to transpose correctly, you should trace the elements along the input and figure out what axes you need to jump to get to each one in the output. The transposition follows accordingly. Divakar's answer does a sterling job of explaining this.
要理解如何正确地进行转置,您应该沿着输入跟踪元素,并找出需要跳转到输出中的每个坐标轴。接下来的换位。迪瓦卡的回答很好地解释了这一点。