我会尝试阐述@Divaker
提出的问题。
In [522]: arr = np.arange(2*2*3*4).reshape(2,2,3,4)
In [523]: arr
Out[523]:
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]]],
[[[24, 25, 26, 27],
[28, 29, 30, 31],
[32, 33, 34, 35]],
[[36, 37, 38, 39],
[40, 41, 42, 43],
[44, 45, 46, 47]]]])
4是最内层的维度,因此它将数组显示为3x4个块。如果您注意空格和[],则会看到有2x2个块。
当我们使用reshape
时,请注意发生了什么:
In [524]: arr1 = arr.reshape(2,2,-1)
In [525]: arr1
Out[525]:
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]],
[[24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35],
[36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47]]])
现在它是2个2x12块。您可以对这些12个元素行进行任何操作,并将它们重新塑形为3x4块。
In [526]: arr1.reshape(2,2,3,4)
Out[526]:
array([[[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
...
但我也可以在最后一个维度上分割这个数组。np.split
可以做到,但列表推导更容易理解:
In [527]: alist = [arr[...,i] for i in range(4)]
In [528]: alist
Out[528]:
[array([[[ 0, 4, 8],
[12, 16, 20]],
[[24, 28, 32],
[36, 40, 44]]]),
array([[[ 1, 5, 9],
[13, 17, 21]],
[[25, 29, 33],
[37, 41, 45]]]),
array([[[ 2, 6, 10],
[14, 18, 22]],
[[26, 30, 34],
[38, 42, 46]]]),
array([[[ 3, 7, 11],
[15, 19, 23]],
[[27, 31, 35],
[39, 43, 47]]])]
这个包含4个(2,2,3)的数组。请注意,3个元素的行在4d显示中显示为列。
我可以使用np.stack
将其重组成一个4d数组(类似于np.array
,但可以更好地控制如何连接数组):
In [529]: np.stack(alist, axis=-1)
Out[529]:
array([[[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
...
[[36, 37, 38, 39],
[40, 41, 42, 43],
[44, 45, 46, 47]]]])
==========
split
的等效方法是 [x[...,0] for x in np.split(arr, 4, axis=-1)]
。没有索引的 split 会产生 (2, 2, 3, 1) 的数组。
collapse_dims
会产生以下结果(以我的示例为例):
In [532]: np.rollaxis(arr,-1,2).reshape(arr.shape[0],arr.shape[1],-1)
Out[532]:
array([[[ 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11],
[12, 16, 20, 13, 17, 21, 14, 18, 22, 15, 19, 23]],
[[24, 28, 32, 25, 29, 33, 26, 30, 34, 27, 31, 35],
[36, 40, 44, 37, 41, 45, 38, 42, 46, 39, 43, 47]]])
一个 (2,2,12) 的数组,但是行内元素的顺序不同。在展开之前,它会对内部的两个维度进行转置。
In [535]: arr[0,0,:,:].ravel()
Out[535]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
In [536]: arr[0,0,:,:].T.ravel()
Out[536]: array([ 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11])
将其恢复到原始顺序需要另一个滚动或转置
In [542]: arr2.reshape(2,2,4,3).transpose(0,1,3,2)
Out[542]:
array([[[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
....
[[36, 37, 38, 39],
[40, 41, 42, 43],
[44, 45, 46, 47]]]])
a
:(64, 64, 2, 5)
,在输出数组out
中应该将a[:,:,:,0]
放置在哪里? - Divakarnumpy
中,最后一个维度是最内部的维度。如果您在 (N,2,3) 数组上进行迭代,则将使用 N 个 (2,3) 数组。MATLAB 使用相反的顺序;第一个是最内部的,最后一个是最外部的。这两种语言显示 3D 数组的方式都反映了这种顺序。 - hpaulj