numpy.rot90 对 3D 和更高阶数组的旋转的视觉理解,维数大于 3 的 ndarrays
visual understanding of rotation by numpy.rot90 for 3D and higher order arrays, ndarrays of dimension greater than 3
我试图理解 3D numpy 数组的单个 90 度旋转,但发现很难形象化(因此很难理解旋转过程本身)。
对于二维的情况,似乎很容易做到。例如,考虑以下代码片段,它对二维数组进行 90 度逆时针旋转:
In [222]: m = np.arange(6).reshape((2,3))
In [223]: m
Out[223]:
array([[0, 1, 2],
[3, 4, 5]])
二维阵列的 90° 变换
<--------\
array([[0, 1, 2],\ # anti-clockwise
[3, 4, 5]])\ # rotation
\
||
In [224]: np.rot90(m)
Out[224]:
array([[2, 5],
[1, 4],
[0, 3]])
但是对于 3D 和更高维数组,事情变得复杂了。同样,作为示例,让我们考虑一个简单的 3D 数组:
In [219]: m = np.arange(12).reshape((2,2,3))
In [220]: m
Out[220]:
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
In [221]: np.rot90(m)
Out[221]:
array([[[ 3, 4, 5],
[ 9, 10, 11]],
[[ 0, 1, 2],
[ 6, 7, 8]]])
查看上面的输出,我无法理解旋转对数组的作用。是否有简化的流程来理解这种转变?形状我也看了,差不多,这就更难理解了
In [227]: np.rot90(m).shape
Out[227]: (2, 2, 3)
我对理解这个转换特别感兴趣,因为它总是 returns 原始数组缓冲区的一个新的“view”,这对写作非常有用在内存和时间方面的高性能代码。如果您对此有任何想法,请分享!
根据转置和翻转表达您的 2d 案例:
In [182]: m = np.arange(6).reshape((2,3))
In [183]: m
Out[183]:
array([[0, 1, 2],
[3, 4, 5]])
In [184]: m.transpose(1,0)
Out[184]:
array([[0, 3],
[1, 4],
[2, 5]])
In [185]: m.transpose(1,0)[::-1, :]
Out[185]:
array([[2, 5],
[1, 4],
[0, 3]])
在 3d 情况下,它似乎做同样的事情 - 第 3 轴标记:
In [188]: m.transpose(1,0,2)[::-1, :]
Out[188]:
array([[[ 3, 4, 5],
[ 9, 10, 11]],
[[ 0, 1, 2],
[ 6, 7, 8]]])
如果我指定第二对轴,它会做同样的事情,但第一对会继续运行:
In [189]: np.rot90(m, axes=(1,2))
Out[189]:
array([[[ 2, 5],
[ 1, 4],
[ 0, 3]],
[[ 8, 11],
[ 7, 10],
[ 6, 9]]])
In [190]: _.shape
Out[190]: (2, 3, 2)
In [191]: m.transpose(0,2,1)[:,::-1, :]
Out[191]:
array([[[ 2, 5],
[ 1, 4],
[ 0, 3]],
[[ 8, 11],
[ 7, 10],
[ 6, 9]]])
不同的k
需要不同的策略。例如 2 我打赌它只是翻转。
===
Out[188]
显示并不能帮助我们可视化旋转,因为它涉及第一维平面和第二维行。但是如果我们选择一个 3 维列,并比较原始和旋转,我们可以看到相同的 2d 旋转:
In [192]: m[:,:,0]
Out[192]:
array([[0, 3],
[6, 9]])
In [193]: Out[188][:,:,0]
Out[193]:
array([[3, 9],
[0, 6]])
3d 数组并不总是表示 3d 直角棱镜。它可以改为具有 3 个颜色通道的 2d 图像。这个 m
旋转然后在不改变颜色的情况下旋转图像。默认 'plane/row/column' 显示并不能帮助我们形象化这样的图像。
我试图理解 3D numpy 数组的单个 90 度旋转,但发现很难形象化(因此很难理解旋转过程本身)。
对于二维的情况,似乎很容易做到。例如,考虑以下代码片段,它对二维数组进行 90 度逆时针旋转:
In [222]: m = np.arange(6).reshape((2,3))
In [223]: m
Out[223]:
array([[0, 1, 2],
[3, 4, 5]])
二维阵列的 90° 变换
<--------\
array([[0, 1, 2],\ # anti-clockwise
[3, 4, 5]])\ # rotation
\
||
In [224]: np.rot90(m)
Out[224]:
array([[2, 5],
[1, 4],
[0, 3]])
但是对于 3D 和更高维数组,事情变得复杂了。同样,作为示例,让我们考虑一个简单的 3D 数组:
In [219]: m = np.arange(12).reshape((2,2,3))
In [220]: m
Out[220]:
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
In [221]: np.rot90(m)
Out[221]:
array([[[ 3, 4, 5],
[ 9, 10, 11]],
[[ 0, 1, 2],
[ 6, 7, 8]]])
查看上面的输出,我无法理解旋转对数组的作用。是否有简化的流程来理解这种转变?形状我也看了,差不多,这就更难理解了
In [227]: np.rot90(m).shape
Out[227]: (2, 2, 3)
我对理解这个转换特别感兴趣,因为它总是 returns 原始数组缓冲区的一个新的“view”,这对写作非常有用在内存和时间方面的高性能代码。如果您对此有任何想法,请分享!
根据转置和翻转表达您的 2d 案例:
In [182]: m = np.arange(6).reshape((2,3))
In [183]: m
Out[183]:
array([[0, 1, 2],
[3, 4, 5]])
In [184]: m.transpose(1,0)
Out[184]:
array([[0, 3],
[1, 4],
[2, 5]])
In [185]: m.transpose(1,0)[::-1, :]
Out[185]:
array([[2, 5],
[1, 4],
[0, 3]])
在 3d 情况下,它似乎做同样的事情 - 第 3 轴标记:
In [188]: m.transpose(1,0,2)[::-1, :]
Out[188]:
array([[[ 3, 4, 5],
[ 9, 10, 11]],
[[ 0, 1, 2],
[ 6, 7, 8]]])
如果我指定第二对轴,它会做同样的事情,但第一对会继续运行:
In [189]: np.rot90(m, axes=(1,2))
Out[189]:
array([[[ 2, 5],
[ 1, 4],
[ 0, 3]],
[[ 8, 11],
[ 7, 10],
[ 6, 9]]])
In [190]: _.shape
Out[190]: (2, 3, 2)
In [191]: m.transpose(0,2,1)[:,::-1, :]
Out[191]:
array([[[ 2, 5],
[ 1, 4],
[ 0, 3]],
[[ 8, 11],
[ 7, 10],
[ 6, 9]]])
不同的k
需要不同的策略。例如 2 我打赌它只是翻转。
===
Out[188]
显示并不能帮助我们可视化旋转,因为它涉及第一维平面和第二维行。但是如果我们选择一个 3 维列,并比较原始和旋转,我们可以看到相同的 2d 旋转:
In [192]: m[:,:,0]
Out[192]:
array([[0, 3],
[6, 9]])
In [193]: Out[188][:,:,0]
Out[193]:
array([[3, 9],
[0, 6]])
3d 数组并不总是表示 3d 直角棱镜。它可以改为具有 3 个颜色通道的 2d 图像。这个 m
旋转然后在不改变颜色的情况下旋转图像。默认 'plane/row/column' 显示并不能帮助我们形象化这样的图像。