阿波罗的战车
我喜欢使用具有不同值和维度的示例数组,例如np.arange(24).reshape(2,3,4).在这种情况下,我也查看了代码。经过一些准备工作以确保axes和k正确后,它会根据 的 4 个可能值执行不同的操作k。axes定义一个“平面”。对于 3d 阵列,axes=(0,1)可以将其视为绕第三轴 (2) 的旋转,想象一个垂直于该“平面”的“矢量”。但代码中使用的是这些轴值。虽然我怀疑我们可以使用基于三角的旋转矩阵构造等效运算,但此代码不执行任何计算。(请注意,整数不会更改为浮点数。)k=0没有改变任何内容:In [104]: np.rot90(m,k=0, axes=(0,1))Out[104]: array([[[ 0, 1, 2, 3], # shape (2,3,4) [ 4, 5, 6, 7], [ 8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]])k=1涉及翻转和转置In [105]: np.rot90(m,k=1, axes=(0,1))Out[105]: array([[[ 8, 9, 10, 11], # shape (3,2,4) [20, 21, 22, 23]], [[ 4, 5, 6, 7], [16, 17, 18, 19]], [[ 0, 1, 2, 3], [12, 13, 14, 15]]])k=2更简单——只需在两个轴上翻转即可。这很容易想象。最后一个维度不变(跨行),但平面和行相反:In [106]: np.rot90(m,k=2, axes=(0,1))Out[106]: array([[[20, 21, 22, 23], [16, 17, 18, 19], [12, 13, 14, 15]], [[ 8, 9, 10, 11], [ 4, 5, 6, 7], [ 0, 1, 2, 3]]])k=3先进行翻转,然后进行转置In [107]: np.rot90(m,k=3, axes=(0,1))Out[107]: array([[[12, 13, 14, 15], # again (3,2,4) [ 0, 1, 2, 3]], [[16, 17, 18, 19], [ 4, 5, 6, 7]], [[20, 21, 22, 23], [ 8, 9, 10, 11]]])看看步伐:In [111]: m.stridesOut[111]: (96, 32, 8)In [112]: np.rot90(m,k=2, axes=(0,1)).stridesOut[112]: (-96, -32, 8) # the double flip转置会改变顺序,而翻转会再次改变符号:In [113]: np.rot90(m,k=1, axes=(0,1)).stridesOut[113]: (-32, 96, 8)In [114]: np.rot90(m,k=3, axes=(0,1)).stridesOut[114]: (32, -96, 8)因为它只是使用flip并且transpose结果是view.更简单的 (1,3,4) 数组在表示一个平面中的值的数组((3,4) 数组)中进行可视化可能更容易:In [120]: m = np.arange(12).reshape(1,3,4)In [121]: mOut[121]: array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]])In [122]: np.rot90(m,k=2, axes=(1,2))Out[122]: array([[[11, 10, 9, 8], [ 7, 6, 5, 4], [ 3, 2, 1, 0]]])In [123]: np.rot90(m,k=1, axes=(1,2)) # visualize a counterclockwise rotationOut[123]: array([[[ 3, 7, 11], [ 2, 6, 10], [ 1, 5, 9], [ 0, 4, 8]]])In [124]: np.rot90(m,k=3, axes=(1,2)) # clockwiseOut[124]: array([[[ 8, 4, 0], [ 9, 5, 1], [10, 6, 2], [11, 7, 3]]])k=3也可以看作是通过 1 和 2 连续逆时针旋转。