在 NumPy 中将 4D 数组重塑为 2D 数组背后的直觉和想法 [英] Intuition and idea behind reshaping 4D array to 2D array in NumPy
问题描述
同时为 Kronecker-product
>教学原因(不使用明显且现成的np.kron()
),我获得了一个4维数组作为中间结果,我必须对其进行整形以获得最终结果结果.
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.
但是,我仍然无法解决重塑这些高维数组的问题.我有这个 4D
数组:
But, I still can't wrap my head around reshaping these high dimensional arrays. I have this 4D
array:
array([[[[ 0, 0],
[ 0, 0]],
[[ 5, 10],
[15, 20]]],
[[[ 6, 12],
[18, 24]],
[[ 7, 14],
[21, 28]]]])
这是(2, 2, 2, 2)
的形状,我想把它改造成(4,4)
.有人可能认为这很明显与
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
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]])
如您所见,预期结果中的所有元素都存在于4D
数组中.我只是无法根据需要正确地进行重塑.除了答案之外,关于如何对这种高维数组进行 reshape
的一些解释将非常有帮助.谢谢!
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!
推荐答案
nd
到 nd
转换的一般思路
将 nd
转换为 nd
的想法只使用两件事 -
General idea for nd
to nd
transformation
The idea with such nd
to nd
transformation is using just two things -
置换轴(使用
numpy.转置
或 <代码>numpy.moveaxis 或numpy.rollaxis
如果所需的置换顺序是滚动顺序或numpy.swapaxes
如果只需要交换两个轴)和
Permute axes (with
numpy.transpose
ornumpy.moveaxis
ornumpy.rollaxis
if the needed permute order is a rolled one ornumpy.swapaxes
if just two axes need to be swapped) and
重塑.
置换轴: 获取顺序,使展平版本对应于输出的展平版本.因此,如果您以某种方式最终使用它两次,请再次查看,因为您不应该这样做.
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
回溯法
最安全的解决方法,给定输入和输出是通过,可以称为回溯方法,即分割输入的轴(当从较小的nd
nd
) 或分割输出的轴(从较大的 nd
到较小的 nd
时).拆分的想法是使较小的 nd
的暗淡数量与较大的 nd
相同.然后,研究输出的步幅并将其与输入匹配以获得所需的置换顺序.最后,如果最后一个是较小的 nd
一个,则最后可能需要重塑(默认方式或 C 顺序)以合并轴.
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.
如果输入和输出都具有相同数量的暗淡,那么我们需要将两者分开并分成块并研究它们彼此的步幅.在这种情况下,我们应该有额外的块大小输入参数,但这可能是题外话.
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.
让我们使用这个特定案例来演示如何应用这些策略.在这里,输入是4D
,而输出是2D
.所以,很可能,我们不需要 reshape 来分裂.所以,我们需要从排列轴开始.因为,最终的输出不是 4D
,而是 2D
,所以我们需要在最后进行重塑.
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.
现在,这里的输入是:
In [270]: a
Out[270]:
array([[[[ 0, 0],
[ 0, 0]],
[[ 5, 10],
[15, 20]]],
[[[ 6, 12],
[18, 24]],
[[ 7, 14],
[21, 28]]]])
预期的输出是:
In [271]: out
Out[271]:
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
此外,这是一个较大的 nd
到较小的 nd
转换,因此回溯方法将涉及拆分输出并研究其 strides 并匹配输入中的相应值:
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 :
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]])
因此,所需的排列顺序是 (2,0,3,1)
:
Hence, the permuted order needed is (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]])
更多示例
我挖掘了我的历史,发现很少有基于 nd
到 nd
转换的 Q&As
.这些可以作为其他示例案例,尽管解释较少(主要是).如前所述,最多两个 reshapes
和最多一个 swapaxes
/transpose
可以在任何地方完成这项工作.它们列在下面:
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 :
- Python 将 3d 数组重塑为 2d
- 使用 python/numpy 重塑数组
- 合并非重叠数组块
- 从 Numpy 3D 数组转换为 2D数组
- 如何在 numpy 中使用 reshape 将 N 长度的向量重塑为 3x(N/3) 矩阵
- 从 4D 列表构建图像
- 重塑/组合多个子-多维空间中一个矩阵的矩阵
- 将各种小的二维矩阵交织成更大的矩阵一个>
- 如何按 3X3 检索每个部分?
- 将 3D Numpy 数组重塑为 2D 数组
- 通过更大的矩阵迭代子矩阵
- 将 2D numpy 数组重组为 3D
- Numpy 改变形状从 (3, 512, 660, 4) 到 (3,2048,660,1)
- Numpy:旋转 M 的子矩阵 m
- 将 3D numpy 数组拆分为 3D 块
- 将 3D 矩阵转换为级联 2D 矩阵
- 重新排列 numpy 数组
- Numpy:沿指定轴重塑数组
- 如何从二维数组构造二维数组
- 如何从子矩阵形成矩阵?
- Python:将 3D 图像系列重塑为像素系列
这篇关于在 NumPy 中将 4D 数组重塑为 2D 数组背后的直觉和想法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!