Python NumPy将4D阵列重塑为2D阵列背后的直觉和想法
由于教学原因(没有使用显而易见的现成的Python NumPy将4D阵列重塑为2D阵列背后的直觉和想法,python,arrays,numpy,multidimensional-array,reshape,Python,Arrays,Numpy,Multidimensional Array,Reshape,由于教学原因(没有使用显而易见的现成的np.kron()),我实现了一个4维数组作为中间结果,我必须对其进行重塑以获得最终结果 但是,我仍然无法集中精力重塑这些高维阵列。我有这个4D阵列: array([[[[ 0, 0], [ 0, 0]], [[ 5, 10], [15, 20]]], [[[ 6, 12], [18, 24]], [[ 7, 14], [21,
np.kron()
),我实现了一个4维数组作为中间结果,我必须对其进行重塑以获得最终结果
但是,我仍然无法集中精力重塑这些高维阵列。我有这个4D
阵列:
array([[[[ 0, 0],
[ 0, 0]],
[[ 5, 10],
[15, 20]]],
[[[ 6, 12],
[18, 24]],
[[ 7, 14],
[21, 28]]]])
这是(2,2,2,2)
的形状,我想把它改成(4,4)
。有人可能会认为这显然与
np.reshape(my4darr, (4,4))
但是,上述重塑并未给出预期结果,即:
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
如您所见,预期结果中的所有元素都存在于
4D
数组中。我就是不知道如何根据需要正确地进行整形。除了答案之外,解释一下如何对这种高维数组进行整形
,将非常有帮助。谢谢 看起来你在找一个接一个的
为了帮助您理解为什么需要换位,让我们分析一下形状不正确的输出(通过单个
restrape
调用获得),以了解它不正确的原因
此结果的简单2D重塑版本(无任何换位)如下所示-
x.reshape(4, 4)
array([[ 0, 0, 0, 0],
[ 5, 10, 15, 20],
[ 6, 12, 18, 24],
[ 7, 14, 21, 28]])
现在考虑这个输出相对于你预期的输出-< /P>
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
start
| /| /| /|
|/ | / |/ |
/ / /
/ / /
| /| / | /|
|/ |/ |/ |
end
您会注意到,实际结果是通过对形状不正确的输出进行类似Z的遍历获得的-
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
start
| /| /| /|
|/ | / |/ |
/ / /
/ / /
| /| / | /|
|/ |/ |/ |
end
这意味着您必须以不同的步幅在阵列上移动才能获得实际结果。总之,简单的重塑是不够的。必须对原始数组进行转置,使这些类Z元素彼此相邻,以便后续的整形调用提供所需的输出
为了理解如何正确转置,您应该沿着输入跟踪元素,并找出需要跳转哪些轴才能到达输出中的每个轴。相应地,换位如下。非常出色地解释了这一点。从nd
到nd
转换的总体思路
这种nd
到nd
转换的思想只使用了两个方面-
- 置换轴(带或,或如果所需的置换顺序是滚动的,或如果只需要交换两个轴),以及
- 重塑
[ Reshape ] ---> [ Permute axes ] ---> [ Reshape ]
Create more axes Bring axes Merge axes
into correct order
回溯法
考虑到输入和输出,最安全的解决方法是通过所谓的回溯法,即拆分输入轴(从较小的nd
到较大的nd
)或拆分输出轴(从较大的nd
到较小的nd
)。拆分的想法是使较小的nd
的DIM数与较大的nd
的DIM数相同。然后,研究输出的步幅,并将其与输入匹配,以获得所需的排列顺序。最后,如果最后一个是较小的nd
轴,则可能需要在末端进行重塑(默认方式或C顺序),以合并轴
如果输入和输出具有相同数量的DIM,那么我们需要将两者分割成块,并研究它们之间的步幅。在这种情况下,我们应该有块大小的附加输入参数,但这可能与主题无关
例子
让我们用这个具体案例来演示如何应用这些策略。在这里,输入是4D
,而输出是2D
。所以,最有可能的是,我们不需要重塑来分割。所以,我们需要从排列轴开始。由于最终输出不是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
转换,因此回溯方法将涉及,分割输出并研究其结果,并与输入中的相应值进行匹配:
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 [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
。这些可以作为其他案例,尽管解释较少(大部分)。如前所述,最多两个重塑
,最多一个交换
/转置
在任何地方都起作用。它们列在下面:
转置
和重塑
封面
例如,下面的代码
n, m = 4, 2
arr = np.arange(n*n*m*m).reshape(n,n,m,m)
for permut in itertools.permutations(range(4)):
arr2 = (arr.transpose(permut)).reshape(n*m, n*m)
print(permut, arr2[0])
使用
transpose
+restrape
可以从四维数组中获得所有信息。因为,我知道输出应该是什么样子,所以我只选择显示正确答案的排列。如果我没有得到我想要的,那么转置
+重塑
就不足以涵盖我的情况,我必须做一些更复杂的事情。。。。或者在t期间翻转它