NumPy的transpose()方法如何置换数组的轴?

时间:2015-08-16 10:51:08

标签: python arrays numpy transpose

In [28]: arr = np.arange(16).reshape((2, 2, 4))

In [29]: arr
Out[29]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])


In [32]: arr.transpose((1, 0, 2))
Out[32]: 
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

当我们将一个整数元组传递给transpose()函数时,会发生什么?

具体来说,这是一个3D数组:当我传递轴(1, 0 ,2)的元组时,NumPy如何转换数组?你能解释一下这些整数所指的行或列吗?什么是NumPy背景下的轴号?

4 个答案:

答案 0 :(得分:2)

在C表示法中,您的数组将是:

int arr[2][2][4]

是具有2个2D阵列的3D阵列。每个2D阵列都有2个1D阵列,每个1D阵列都有4个元素。

所以你有三个维度。轴为0,1,2,尺寸为2,2,4。这正是numpy如何处理N维阵列的轴。

因此,arr.transpose((1, 0, 2))将取轴1并将其置于位置0,轴0并将其置于位置1,将轴2置于位置2.您有效地置换轴:

0 -\/-> 0
1 -/\-> 1
2 ----> 2

换句话说,1 -> 0, 0 -> 1, 2 -> 2。目标轴始终按顺序排列,因此您只需指定源轴。按顺序读取元组:(1, 0, 2)

在这种情况下,新的数组维度再次为[2][2][4],因为0和1轴的大小相同(2)。

更有趣的是(2, 1, 0)的转置,它为您提供了[4][2][2]的数组。

0 -\ /--> 0
1 --X---> 1
2 -/ \--> 2

换句话说,2 -> 0, 1 -> 1, 0 -> 2。按顺序读取元组:(2, 1, 0)

>>> arr.transpose((2,1,0))
array([[[ 0,  8],
        [ 4, 12]],

       [[ 1,  9],
        [ 5, 13]],

       [[ 2, 10],
        [ 6, 14]],

       [[ 3, 11],
        [ 7, 15]]])

您最终获得了int[4][2][2]

如果所有尺寸都不同,您可能会更好地理解,因此您可以看到每个轴的位置。

为什么第一个内部元素[0, 8]?因为如果您将3D阵列可视化为两张纸,08排成一行,一张在纸上,另一张在另一张纸上,两者都在左上角。通过转置(2, 1, 0),你说你想要纸张到纸张的方向从左到右沿纸张行进,从左到右的方向现在从纸张到纸张。你有4个元素从左到右,所以现在你有四张纸。你有2篇论文,所以现在你有2个元素从左到右。

抱歉可怕的ASCII艺术。 ¯\_(ツ)_/¯

答案 1 :(得分:0)

似乎是一个问题,示例出自Wes McKinney撰写的《 Python for Data Analysis 》一书。 {em>第4.1章中提到了transpose的此功能。转置数组和交换轴。

  

对于高维数组,transpose将接受一个轴号元组来置换轴(以增加思维的弯曲度)。

此处“置换”是指“重新排列”,因此请重新排列轴的顺序。

.transpose(1, 0, 2)中的数字确定与原始轴相比如何更改轴的顺序。通过使用.transpose(1, 0, 2),我们的意思是“将第一把斧头改为第二把斧头”。如果我们使用.transpose(0, 1, 2),则数组将保持不变,因为没有任何更改。这是默认顺序。

书中带有(2, 2, 4)大小的数组的示例不是很清楚,因为第一轴和第二轴的大小相同。因此,除了对行arr[0, 1]arr[1, 0]进行重新排序外,最终结果似乎没有改变。

如果我们尝试使用3维数组(每个维具有不同大小)的不同示例,则重排部分将变得更加清晰。

In [2]: x = np.arange(24).reshape(2, 3, 4)

In [3]: x
Out[3]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])

In [4]: x.transpose(1, 0, 2)
Out[4]: 
array([[[ 0,  1,  2,  3],
        [12, 13, 14, 15]],

       [[ 4,  5,  6,  7],
        [16, 17, 18, 19]],

       [[ 8,  9, 10, 11],
        [20, 21, 22, 23]]])

此处,原始数组大小为(2, 3, 4)。我们更改了第一和第二,因此其大小变为(3, 2, 4)。如果我们仔细观察,看看重新排列是如何发生的;数字数组似乎已在特定模式下发生了变化。使用@ RobertB的书面类比,如果我们要取2个数字块,并将每个数字写在纸上,然后从每张纸上取一行,以构造数组的一个维,则现在有一个从最外层到最内层的3x2x4大小的数组。

[ 0,  1,  2,  3] \ [12, 13, 14, 15]

[ 4,  5,  6,  7] \ [16, 17, 18, 19]

[ 8,  9, 10, 11] \ [20, 21, 22, 23]

使用不同大小的数组并更改不同的轴以更好地了解其工作原理可能是个好主意。

答案 2 :(得分:0)

我也在 Wes McKinney 的 Python for Data Analysis 中遇到了这个问题。

我将展示求解 3 维张量的最简单方法,然后描述可用于 n 维张量的一般方法。

简单的 3 维张量示例

假设你有 (2,2,4)-张量

[[[ 0  1  2  3]
  [ 4  5  6  7]]

 [[ 8  9 10 11]
  [12 13 14 15]]]

如果我们看每个点的坐标,它们是这样的:

[[[ (0,0,0)  (0,0,1)  (0,0,2)  (0,0,3)]
  [ (0,1,0)  (0,1,1)  (0,1,2)  (0,1,3)]]

 [[ (1,0,0)  (1,0,1) (1,0,2) (0,0,3)]
  [ (1,1,0)  (1,1,1) (1,1,2) (0,1,3)]]

现在假设上面的数组是 example_array 并且我们要执行操作:example_array.transpose(1,2,0)

对于 (1,2,0) 变换,我们将坐标打乱如下(请注意,此特定变换相当于“左移”:

(0,0,0)  ->  (0,0,0)
(0,0,1)  ->  (0,1,0)
(0,0,2)  ->  (0,2,0)
(0,0,3)  ->  (0,3,0)
(0,1,0)  ->  (1,0,0)
(0,1,1)  ->  (1,1,0)
(0,1,2)  ->  (1,2,0)
(0,1,3)  ->  (1,3,0)
(1,0,0)  ->  (0,0,1)
(1,0,1)  ->  (0,1,1)
(1,0,2)  ->  (0,2,1)
(0,0,3)  ->  (0,3,0)
(1,1,0)  ->  (1,0,1)
(1,1,1)  ->  (1,1,1)
(1,1,2)  ->  (1,2,1)
(0,1,3)  ->  (1,3,0)

现在,对于每个原始值,将其放入结果矩阵中的移位坐标中。

例如,值 10 在原始矩阵中有坐标 (1, 0, 2),在结果矩阵中有坐标 (0, 2, 1)。它被放置在该子矩阵第三行的第一个二维张量子矩阵中,在该行的第二列。

因此,结果矩阵为:

array([[[ 0,  8],
        [ 1,  9],
        [ 2, 10],
        [ 3, 11]],

       [[ 4, 12],
        [ 5, 13],
        [ 6, 14],
        [ 7, 15]]])

一般的 n 维张量方法

对于n维张量,算法是一样的。考虑原始矩阵中单个值的所有坐标。随机播放该单个坐标的轴。将该值放入结果矩阵中生成的混洗坐标中。对所有剩余值重复此操作。

答案 3 :(得分:-3)

总结 a.transpose()[i,j,k] = a [k,j,i]

a = np.array( range(24), int).reshape((2,3,4))
a.shape gives (2,3,4)
a.transpose().shape gives (4,3,2)  shape tuple is reversed.

当传递元组参数时,根据元组置换轴。 例如

a = np.array(range(24),int).reshape((2,3,4))

a [i,j,k]等于a.transpose((2,0,1))[k,i,j]

轴0获得第二名

第1轴获得第3名

轴2故事第一名

当然我们需要注意传递给transpose的元组参数中的值是唯一的并且在范围内(轴的数量)