NumPy中的轴-维度-秩

NumPy中的轴-维度-秩

看了某个要求,需要numpy和pandas,先看了numpy,才看到NumPy数组,就已经懵了,NumPy的维度(dimension)、轴(axis)和秩(rank)这几个概念有点绕。

关于维度:In NumPy dimension are called axes。意思是维度称为轴,和学生时代学习的对比,一维不谈,二维空间(x轴和y轴),只需要对应的x和y坐标,就能在二维空间中确定一个点;三维空间(x轴、y轴和z轴),只需要x坐标,y坐标和z坐标,就能在三维空间确定一个固定的点。类比到NumPy中,一维数组,轴的个数就为一;二维数组,轴的个数就为二。

而秩(rank)就是轴的数量,一维数组,秩是1,二维数组,秩是2这样。

NumPy可以用ndimshape来获取秩和维度
源码:

1
2
3
4
5
6
7
8
9
10
11
ndim = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
"""Number of array dimensions.

Examples
--------
>>> x = np.array([1, 2, 3])
>>> x.ndim
1
>>> y = np.zeros((2, 3, 4))
>>> y.ndim
3"""

秩是维度的数量(轴的数量)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
shape = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
"""Tuple of array dimensions.

The shape property is usually used to get the current shape of an array,
but may also be used to reshape the array in-place by assigning a tuple of
array dimensions to it. As with `numpy.reshape`, one of the new shape
dimensions can be -1, in which case its value is inferred from the size of
the array and the remaining dimensions. Reshaping an array in-place will
fail if a copy is required.

Examples
--------
>>> x = np.array([1, 2, 3, 4])
>>> x.shape
(4,)

直接用例子来辅助理解:

首先记住:NumPy对于轴的编号由外向内,从行到列。

一维数组:

1
2
3
4
5
6
7
8
9
10
11
import  numpy as np

# 一维数组
a = np.array([1, 2, 3])
print(a.ndim)
print(a.shape)


# 输出结果
1
(3,)

示例的一维数组,秩为1,维度返回值(3,),表示该数组在一维空间,有三个数据

二维数组:

1
2
3
4
5
6
7
8
# 二维数组
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a.ndim)
print(a.shape)

# 输出
2
(2, 3)

示例二维数据,秩为2,维度返回值(2, 3),表示该二维数组有两行三列(0轴长度为2,1轴长度为3)
示意图:

二维数组中,轴0表示数组的行,轴1表示数组的列

二维数组,可以看做是在0轴方向叠加一维数组,相应的,数组求和,0轴方向结果应该为:[5, 7, 9],1轴方向结果应该为[6, 15]
验证一下:

1
2
3
4
5
6
print(a.sum(axis=0))
print(a.sum(axis=1))

# 输出
[5 7 9]
[ 6 15]

三维数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 三维数组
a = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]], [[13, 14, 15], [16, 17, 18]]])
b = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
c = np.array([[[1, 2, 3]]])
# print(a)
print(a.ndim)
print(a.shape)

print(b.ndim)
print(b.shape)

print(c.ndim)
print(c.shape)

# 输出
3
(3, 2, 3)
3
(2, 2, 3)
3
(1, 1, 3)

以a为例,秩为3,数组维度返回(3, 2, 3),表示0轴长度为3,1轴长度为2,2轴长度为3,
示意图:

从示意图可以看出,三维数组可以理解为二维数组在0轴方向的叠加;
0轴方向求和,结果应该是个二维数组:[[21, 24, 27], [30, 33, 36]]
1轴方向求和,结果应该是二维数组:[[5, 7, 9], [17, 19, 21], [29, 31, 33]]
2轴方向求和,结果应该是二维数组:[[6, 15], [24, 33], [42, 51]]
验证求和计算:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
print(a.sum(axis=0))
print(a.sum(axis=1))
print(a.sum(axis=2))

# 结果输出
[[21 24 27]
[30 33 36]]
=====================
[[ 5 7 9]
[17 19 21]
[29 31 33]]
*********************
[[ 6 15]
[24 33]
[42 51]]

对于更高维度的数组,其实可以采用“降维”的方式进行处理,例如四维数组:

1
2
3
4
5
6
7
8
a = np.array([[[1, 2, 3, 4], [5, 6, 7, 8]], [[9, 10, 11, 12], [13, 14, 15, 16]]])
print(a)

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

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

可以这么看:
A=[1, 2, 3, 4]
B=[5, 6, 7, 8]
C=[9, 10, 11, 12]
D=[13, 14, 15, 16]

原数组就可以重新表示成:[[A, B], [C, D]],一个二维数组
示意图:

此时进行数组求和,是按照向量进行加减法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 三维数组
# a = np.array([[A, B], [C, D]])
# A=[1, 2, 3, 4]
# B=[5, 6, 7, 8]
# C=[9, 10, 11, 12]
# D=[13, 14, 15, 16]
# 二维数组,1轴方向
# A+B=[1+5, 2+6, 3+7, 4+8]=[6, 8, 10, 12]
# C+D=[9+13, 10+14, 11+15, 12+16]=[22, 24, 26, 28]
# 原数组1轴方向求和结果:[[6, 8, 10, 12], [22, 24, 26, 28]]
# 二维数组,0方向
# A+C=[1+9, 2+10, 3+11, 4+12]=[10, 12, 14, 16]
# B+D=[5+13, 6+14, 7+15, 8+16]=[18, 20, 22, 24]
# 原数组0轴方向求和结果:[[10, 12, 14, 16], [18, 20, 22, 24]]
# 原数组2轴方向求和结果即为每个一维数组内元素之和:A=10,B=26,C=42,D=58 --> [[10, 26], [42, 58]]
a = np.array([[[1, 2, 3, 4], [5, 6, 7, 8]], [[9, 10, 11, 12], [13, 14, 15, 16]]])

# print(a)
print(a.sum(axis=0))
print("====================")
print(a.sum(axis=1))
print("....................")
print(a.sum(axis=2))

结果验证:

1
2
3
4
5
6
7
8
[[10 12 14 16]
[18 20 22 24]]
====================
[[ 6 8 10 12]
[22 24 26 28]]
....................
[[10 26]
[42 58]]
文章目录
|