在执行 Kronecker-product
时出于教学原因(没有使用明显且现成的 np.kron()
),我获得了一个 4 维数组作为中间结果,我必须将其 reshape 为得到最终结果。
但是,我仍然无法全神贯注于 reshape 这些高维数组。我有这个 4D
数组:
array([[[[ 0, 0],
[ 0, 0]],
[[ 5, 10],
[15, 20]]],
[[[ 6, 12],
[18, 24]],
[[ 7, 14],
[21, 28]]]])
这是 (2, 2, 2, 2)
的形状,我想将它 reshape 为 (4,4)
。有人可能认为这显然与
np.reshape(my4darr, (4,4))
但是,上面的 reshape 没有给我预期的结果,它是:
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
如您所见,预期结果 中的所有元素都出现在 4D
数组中。我只是无法掌握根据需要正确地进行 reshape 的窍门。除了答案之外,对如何对此类高维数组进行 reshape
的一些解释将非常有帮助。谢谢!
最佳答案
nd
到nd
转换的总体思路
从 nd
到 nd
转换的想法只使用了两件事 -
排列轴(使用
numpy.transpose
或numpy.moveaxis
或numpy.rollaxis
如果需要的排列顺序是滚动的,或者使用numpy.swapaxes
如果只需要交换两个轴)和reshape 。
Permute axes : 获取顺序,使展平版本对应于展平版本的输出。因此,如果您以某种方式最终使用它两次,请再看一遍,因为您不应该这样做。
Reshape : 拆分轴或将最终输出调整为所需的形状。拆分轴主要是在开始时需要的,当输入是 lower-dim 并且我们需要拆分成 block 时。同样,您不应该需要两次以上。
因此,一般我们会分为三个步骤:
[ Reshape ] ---> [ Permute axes ] ---> [ Reshape ]
Create more axes Bring axes Merge axes
into correct order
回溯法
最安全的解决方法,给定输入和输出是直通的,可以称为回溯法,即拆分输入轴(从较小的 nd
到较大的轴nd
) 或拆分输出轴(当从较大的 nd
变为较小的 nd
时)。拆分的想法是使较小的 nd
的 dims 数量与较大的 nd
的相同。然后,研究输出的步长并将其与输入进行匹配以获得所需的排列顺序。最后,如果最后一个是较小的 nd
,最后可能需要 reshape (默认方式或 C 顺序)以合并轴。
如果输入和输出都具有相同数量的 dims,那么我们需要将两者拆分并分成 block 并研究它们相互间的步幅。在这种情况下,我们应该有 block 大小的额外输入参数,但这可能是题外话。
例子
让我们使用这个具体案例来演示如何应用这些策略。在这里,输入是4D
,而输出是2D
。所以,很可能,我们不需要 reshape 来 split 。所以,我们需要从排列轴开始。由于最终输出不是 4D
,而是 2D
,因此我们需要在最后进行整形。
现在,这里的输入是:
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。并匹配输入中的相应值:
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)
:
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]]]])
然后,简单地 reshape 成预期的形状:
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]])
更多示例
我挖掘了我的历史,发现很少有Q&As
基于nd
到nd
的转换。这些可以作为其他示例案例,尽管解释较少(主要是)。如前所述,至多两个 reshapes
和至多一个 swapaxes
/transpose
完成了所有工作。它们列在下面:
- Python Reshape 3d array into 2d
- reshape an array using python/numpy
- Merging non-overlapping array blocks
- Conversion from a Numpy 3D array to a 2D array
- how to reshape an N length vector to a 3x(N/3) matrix in numpy using reshape
- Construct image from 4D list
- 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?
- Reshaping 3D Numpy Array to a 2D array
- Iterate in submatrices through a bigger matrix
- Reorganizing a 2D numpy array into 3D
- Numpy change shape from (3, 512, 660, 4) to (3,2048,660,1)
- Numpy: rotate sub matrix m of M
- Split a 3D numpy array into 3D blocks
- Converting 3D matrix to cascaded 2D Matrices
- Rearranging numpy array
- Numpy: Reshape array along a specified axis
- How to construct 2d array from 2d arrays
- How to form a matrix from submatrices?
- Python: Reshape 3D image series to pixel series
关于python - 在 NumPy 中将 4 维数组 reshape 为 2 维数组背后的直觉和想法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47977238/