kma*_*o23 17 python arrays numpy multidimensional-array reshape
虽然Kronecker-product出于教学原因(没有使用明显的和容易获得的np.kron()),我获得了一个4维数组作为中间结果,我将重塑以获得最终结果.
但是,我仍然无法围绕重塑这些高维阵列.我有这个4D数组:
array([[[[ 0, 0],
[ 0, 0]],
[[ 5, 10],
[15, 20]]],
[[[ 6, 12],
[18, 24]],
[[ 7, 14],
[21, 28]]]])
Run Code Online (Sandbox Code Playgroud)
这是形状(2, 2, 2, 2),我想重塑它(4,4).有人可能会认为这很明显
np.reshape(my4darr, (4,4))
Run Code Online (Sandbox Code Playgroud)
但是,上述重塑并没有给我预期的结果,即:
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
Run Code Online (Sandbox Code Playgroud)
如您所见,预期结果中的所有元素都存在于4D数组中.我根本不能正确地根据需要进行重塑.除了答案之外,如何reshape为这种高维数组做一些解释将是非常有帮助的.谢谢!
Div*_*kar 28
nd来nd改造这样的想法nd来nd变换只使用两件事情-置换轴(带numpy.transpose或者numpy.moveaxis如果需要置换顺序是推出一个或numpy.rollaxis如果只是两个轴需要被交换)和重塑.
置换轴:获取订单,使得展平版本对应于展平版本的输出.所以,如果你以某种方式最终使用它两次,再看一遍,因为你不应该.
重塑:分割轴或将最终输出转换为所需形状.主要在开始时需要拆分轴,此时输入较低且我们需要拆分成块.同样,你不应该需要这两次以上.
因此,通常我们会有三个步骤:
[ Reshape ] ---> [ Permute axes ] ---> [ Reshape ]
Create more axes Bring axes Merge axes
into correct order
Run Code Online (Sandbox Code Playgroud)
反向跟踪方法
考虑到输入和输出是最安全的解决方法,可以称之为反向跟踪方法,即分割输入轴(当从较小numpy.swapaxes到较大时nd)或分割输出轴(当去从更大的nd更小nd).分裂的想法是使较小的nd一个的昏暗数量与较大的一个相同nd.然后,研究输出的步幅并将其与输入匹配以获得所需的置换顺序.最后,如果最后一个是较小的,则可能需要重新整形(默认方式或C顺序)nd来合并轴.
如果输入和输出都具有相同数量的dims,那么我们需要将两者分开并分成块并研究它们相互之间的步幅.在这种情况下,我们应该有块大小的附加输入参数,但这可能是偏离主题的.
让我们使用这个特定的案例来演示如何应用这些策略.在这里,输入是nd,而输出是4D.所以,最有可能的是,我们不需要重塑分裂.因此,我们需要从置换轴开始.因为,最终的输出不是2D,而是4D一个,我们需要在最后重塑.
现在,这里的输入是:
In [270]: a
Out[270]:
array([[[[ 0, 0],
[ 0, 0]],
[[ 5, 10],
[15, 20]]],
[[[ 6, 12],
[18, 24]],
[[ 7, 14],
[21, 28]]]])
Run Code Online (Sandbox Code Playgroud)
预期的产出是:
In [271]: out
Out[271]:
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
Run Code Online (Sandbox Code Playgroud)
此外,这是一个更2D小到更小的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]])
Run Code Online (Sandbox Code Playgroud)
因此,所需的置换顺序是nd:
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]]]])
Run Code Online (Sandbox Code Playgroud)
然后,简单地重塑为预期的形状:
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]])
Run Code Online (Sandbox Code Playgroud)
更多例子
我挖了我的历史,发现一些(2,0,3,1)基于Q&As对nd转变.这些可以作为其他示例案例,尽管解释较少(大多数情况下).如前所述,nd最多只有两个,最多一个reshapes/ swapaxes在各地完成工作.它们列在下面:
cs9*_*s95 11
看起来你正在寻找一个transpose跟随的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]])
Run Code Online (Sandbox Code Playgroud)
为了帮助您理解为什么需要换位,让我们分析您错误形状的输出(通过单个reshape调用获得)以理解为什么它不正确.
这个结果的简单2D重新整形版本(没有任何换位)看起来像这样 -
x.reshape(4, 4)
array([[ 0, 0, 0, 0],
[ 5, 10, 15, 20],
[ 6, 12, 18, 24],
[ 7, 14, 21, 28]])
Run Code Online (Sandbox Code Playgroud)
现在根据您的预期输出考虑此输出 -
array([[ 0, 5, 0, 10],
[ 6, 7, 12, 14],
[ 0, 15, 0, 20],
[18, 21, 24, 28]])
Run Code Online (Sandbox Code Playgroud)
您会注意到您的实际结果是通过类似Z的遍历输出错误形状 -
start
| /| /| /|
|/ | / |/ |
/ / /
/ / /
| /| / | /|
|/ |/ |/ |
end
Run Code Online (Sandbox Code Playgroud)
这意味着您必须以不同的步幅移动数组以获得实际结果.总之,简单的重塑是不够的.您必须转换原始数组,使这些类似Z的元素彼此连续,以便后续的重塑调用为您提供所需的输出.
要了解如何正确转置,您应该沿着输入跟踪元素,并找出需要跳转到输出中的每个轴的轴.相应地进行换位.迪瓦卡的答案很有助于解释这一点.
| 归档时间: |
|
| 查看次数: |
3684 次 |
| 最近记录: |