Numpy加维度的本质

Numpy 加维度的本质

从空间的角度,新加的维度是在 shape 最左边的,就例如(2,3,3)是一个 3*3 方阵在第三维上有两个。
但从每个元素的角度来看,就是在每个元素外套了一层数组。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> A
array([[3, 9, 3],
[9, 7, 6]], dtype=int32)
>>> AA=A[...,None]
>>> AA
array([[[3],
[9],
[3]],

[[9],
[7],
[6]]], dtype=int32)
>>> A[0,0]
np.int32(3)
>>> AA[0,0]
array([3], dtype=int32)

所以 A[i, j]==AA[i, j, 0]
相反,如果在最左边加轴,那么只是在整体上增加一层

1
2
3
4
5
6
7
8
9
10
>>> AAA=A[None,...]
>>> AAA
array([[[3, 9, 3],
[9, 7, 6]]], dtype=int32)
>>> AAA.shape
(1, 2, 3)
>>> AAA[0,0]
array([3, 9, 3], dtype=int32)
>>> A[0]
array([3, 9, 3], dtype=int32)

所以取元素的顺序其实是和 shape 中的顺序是一样的。这是让人感觉空间是在 shape 左边生长的一个原因。
索引和空间是不一样的,从空间上来看,shape 是向左生长的,从数据索引上看,shape 是向右生长的。

至于为什么从 A 到 AA numpy 中会这样显示(即在空间上好像在第三维度上增加),因为 numpy 是列思想,所有标量广播为数组后都会变成列向量,所有数组广播后都会变成列向量即(shape 在左边扩展,这就是为什么在空间上 shape 是向左生长的)。所以 [3, 9, 3] 就变成了

1
2
3
[[3],
[9],
[3]]

AA-a 例子详解:

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
>>> AA
array([[[3],
[9],
[3]],

[[9],
[7],
[6]]], dtype=int32)
>>> np.broadcast_to(AA,(2,3,3))
array([[[3, 3, 3],
[9, 9, 9],
[3, 3, 3]],

[[9, 9, 9],
[7, 7, 7],
[6, 6, 6]]], dtype=int32)
>>> np.broadcast_to(a,(1,1,3))
array([[[9, 7, 2]]], dtype=int32)
>>> np.broadcast_to(AA,(2,3,3))-np.broadcast_to(a,(1,1,3))
array([[[-6, -4, 1],
[ 0, 2, 7],
[-6, -4, 1]],

[[ 0, 2, 7],
[-2, 0, 5],
[-3, -1, 4]]], dtype=int32)
>>> np.broadcast_to(AA,(2,3,3))-np.broadcast_to(a,(1,1,3)) == AA-a
array([[[ True, True, True],
[ True, True, True],
[ True, True, True]],

[[ True, True, True],
[ True, True, True],
[ True, True, True]]])

从结果上来说就是类笛卡尔积,A 中的每一个元素都被 a 中的每一个元素进行了操作。