背景
NumPy 是 Python 的重要库,在数值计算领域有着重要作用。ndarray (N-Dimensional Array, 多维数组) 是NumPy 中定义的数据类型,也是此文探讨的背景。
在初学 NumPy 时,并不能很好理解相关函数中 axis 的作用,查阅资料和思考后,有了较为清晰的理解。
函数
np.stack()
作用
沿新轴堆叠一系列数组形成新的数组。
定义
numpy.stack
(arrays, axis=0, out=None)
array
输入的数组,数据类型为 array_like (list, tuple, ndarray 等),且必须具有相同的形状 (shape)
axis
堆叠的轴
out
(不常用)输出的数组保存在哪里,必须是与产生的数组相同形状的 ndarray 对象
例子
一维 -> 二维
1
2
3
4
5
6
7
8
a = (1,2,3)
b = [4,5,6]
c = np.stack((a,b), axis=0)
"""
c =
[[1 2 3]
[4 5 6]]
"""
1
2
3
4
5
6
7
8
9
a = (1,2,3)
b = [4,5,6]
c = np.stack((a,b), axis=1)
"""
c =
[[1 4]
[2 5]
[3 6]]
"""
二维 -> 三维
1
2
3
4
5
6
7
8
9
10
11
a = ((1,2,3),(4,5,6))
b = [[7,8,9],[10,11,12]]
c = np.stack((a,b), axis=0)
"""
c =
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
"""
1
2
3
4
5
6
7
8
9
10
11
a = ((1,2,3),(4,5,6))
b = [[7,8,9],[10,11,12]]
c = np.stack((a,b), axis=1)
"""
c =
[[[ 1 2 3]
[ 7 8 9]]
[[ 4 5 6]
[10 11 12]]]
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
a = ((1,2,3),(4,5,6))
b = [[7,8,9],[10,11,12]]
c = np.stack((a,b), axis=2)
print(c)
"""
c =
[[[ 1 7]
[ 2 8]
[ 3 9]]
[[ 4 10]
[ 5 11]
[ 6 12]]]
"""
解释
首先,需要理解一个给定的数组中,元素由一组序号(坐标)唯一确定。
对于一维矩阵(向量),可由[列]
(或“下标”)确定元素
对于二维矩阵,可由[行][列]
确定元素
比如
则1可由[0][0]
确定,2可由[0][1]
确定,以此类推
对于三维矩阵而言,可由[层][行][列]
确定元素
比如
则1可由[0][0][0]
确定,2可由[0][0][1]
确定,7可由[1][0][0]
确定,以此类推
在理解了序号表示矩阵的概念后,我们再来理解 axis 的意义。
axis = k
指的是增加了第k个维度。换句话来说,就是在原有坐标的基础上,在第k个位置插入新的坐标,而该坐标的值由array
中输入矩阵的顺序决定(从0开始计数)。
对于一维矩阵生成二维矩阵而言,
axis = 0
则指在第0个维度上插入新的坐标,即增设 行 的坐标。具体来说,是将第零个参数矩阵的所有元素的 行 的坐标设置为0,将第一个参数矩阵的所有元素的 行 的坐标设置为1,原有序号顺延作为第1个维度(列)的坐标。因此,在图像上,如同“上下堆叠”或“竖着叠放”,表示为竖着的 列 的延伸。
axis = 1
则指在第1个维度上插入新的坐标,即增设 列 的坐标。具体来说,是将第零个参数矩阵的所有元素的 列 的坐标设置为0,将第一个参数矩阵的所有元素的 列 的坐标设置为1,原有序号作为第0个维度(行)的坐标。因此,在图像上,如同“左右堆叠”或“横着叠放”,表示为横着的 行 的延伸。
对于二维矩阵生成三维矩阵而言,
axis = 0
则指在第0个维度上插入新的坐标,即增设 层 的坐标。比如数字6由原来的[1][2]
变为[0#][1][2]
。在图像上,如同“前后堆叠”,表示为纵深的 层 的延伸。
axis = 1
则指在第1个维度上插入新的坐标,即原有的 行 坐标变为 层 的坐标,增设新的 行 坐标,列 坐标不变。比如数字6由原来的[1][2]
变为[1][0#][2]
。图像上,如同将二维矩阵每行横着剪开,并依次叠在前一行的背后(“前后堆叠”),最后各矩阵上下拼接(“上下堆叠”),即竖着的 列 的延伸。
axis = 2
则指在第2个维度上插入新的坐标,即原有的 行 坐标变为 层 的坐标,原有的 列 坐标变为 行 的坐标,增设新的 列 坐标。比如数字6由原来的[1][2]
变为[1][2][0#]
。图像上,如同将二维矩阵每行横着剪开,各纸条顺时针旋转90°,并依次叠在前一行的背后(“前后堆叠”),最后来自各矩阵的纸条左右拼接(“左右堆叠”),横着的 行 的延伸。