NumPy 系列文章:

专栏:

NumPy 专栏】【Pandas 专栏】【Matplotlib 专栏

推荐学习资料与网站:

NumPy 中文网】【Pandas 中文网】【Matplotlib 中文网】【NumPy、Matplotlib、Pandas 速查表


1
2
3
4
5
这里是一段防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 TRHX。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/104988137
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!

【1x00】认识 Numpy 中的 nan 和 inf

nan(NAN,Nan):全称 not a number,即不是一个数字
inf(-inf,inf):全称 infinity,inf 表示正无穷,-inf 表示负无穷

以下情况 Numpy 中会出现 nan:

  • 当读取本地的文件为 float 的时候,如果有缺失,就会出现 nan
  • 当做了一个不合适的计算的时候(如:无穷大减去无穷大)

以下情况会出现 inf 或者 -inf:

  • 比如一个数字除以 0,在 Python 中直接会报错,但在 Numpy 中则是一个 inf 或者 -inf

指定一个 nan 或者 inf:

1
2
3
4
5
6
7
8
9
10
11
>>> import numpy as np
>>> a = np.nan
>>> b = np.inf
>>> print(a)
nan
>>> print(b)
inf
>>> type(a)
<class 'float'>
>>> type(b)
<class 'float'>

注意两个 nan 并不相等,而两个 inf 是相等的

1
2
3
4
>>> np.nan == np.nan
False
>>> np.inf == np.inf
True

nan 和任何值计算都为 nan:

1
2
3
4
5
>>> import numpy as np
>>> a = np.array([1, 2, 3, 4, 5])
>>> b = np.array([1, 2, np.nan, 4, np.nan])
>>> print(a+b)
[ 2. 4. nan 8. nan]

【1x01】判断是否为 nan 和 inf

  • isnan:判断元素是否为 nan(非数字)
  • isinf:判断元素是否为正无穷大或负无穷大
  • isposinf:判断元素是否为正无穷大
  • isneginf:判断元素是否为负无穷大
  • isfinite:判断元素是否为有限的(不是非数字,正无穷大和负无穷大中的一个)
1
2
3
4
5
6
7
8
9
10
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [np.nan, 6, 7, np.nan], [9 ,np.nan, 10, 11]])
>>> print(a)
[[ 1. 2. 3. 4.]
[nan 6. 7. nan]
[ 9. nan 10. 11.]]
>>> np.isnan(a)
array([[False, False, False, False],
[ True, False, False, True],
[False, True, False, False]])

【1x02】统计数组中 nan 的个数

1、利用 np.count_nonzero 方法,结合两个 nan 不相等的属性,可以判断数组中 nan 的个数:

1
2
3
4
5
6
7
8
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [np.nan, 6, 7, np.nan], [9 ,np.nan, 10, 11]])
>>> print(a)
[[ 1. 2. 3. 4.]
[nan 6. 7. nan]
[ 9. nan 10. 11.]]
>>> np.count_nonzero(a != a) # 判断 nan 的个数,a != a 即为 nan,nan != nan
3

2、isnan() 方法可以判断哪些是 nan,再结合 np.count_nonzero 方法可以判断数组中 nan 的个数:

1
2
3
4
5
6
7
8
9
10
11
12
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [np.nan, 6, 7, np.nan], [9 ,np.nan, 10, 11]])
>>> print(a)
[[ 1. 2. 3. 4.]
[nan 6. 7. nan]
[ 9. nan 10. 11.]]
>>> np.isnan(a) # np.isnan(a) 与 a != a 效果相同,判断那些是 nan
array([[False, False, False, False],
[ True, False, False, True],
[False, True, False, False]])
>>> np.count_nonzero(np.isnan(a))
3

3、利用 collections 模块的 Counter 方法来统计 nan 的个数(此方法仅适用于一维数组):

1
2
3
4
5
>>> from collections import Counter
>>> import numpy as np
>>> a = np.array([1, 2, np.nan, 4, np.nan])
>>> print(Counter(np.isnan(a)))
Counter({False: 3, True: 2})

【1x03】统计数组中 inf 的个数

1、isinf() 方法可以判断哪些是 inf,再结合 np.count_nonzero 方法可以判断数组中 inf 的个数:

1
2
3
4
5
6
7
8
9
10
11
12
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [np.inf, 6, 7, -np.inf], [9 ,-np.inf, 10, 11]])
>>> print(a)
[[ 1. 2. 3. 4.]
[ inf 6. 7. -inf]
[ 9. -inf 10. 11.]]
>>> np.isinf(a)
array([[False, False, False, False],
[ True, False, False, True],
[False, True, False, False]])
>>> np.count_nonzero(np.isinf(a))
3

2、利用 collections 模块的 Counter 方法来统计 inf 的个数(此方法仅适用于一维数组):

1
2
3
4
5
>>> from collections import Counter
>>> import numpy as np
>>> a = np.array([1, 2, np.inf, 4, -np.inf])
>>> print(Counter(np.isinf(a)))
Counter({False: 3, True: 2})

【1x04】替换 inf 和 nan

numpy.nan_to_num() 方法可以将 nan 替换为零,将 inf 替换为有限数。

1
2
3
4
5
6
7
8
9
10
>>> import numpy as np
>>> a = np.array([[1, np.nan, 3, 4], [np.inf, 6, 7, -np.inf], [9 ,-np.inf, 10, np.nan]])
>>> print(a)
[[ 1. nan 3. 4.]
[ inf 6. 7. -inf]
[ 9. -inf 10. nan]]
>>> print(np.nan_to_num(a))
[[ 1.00000000e+000 0.00000000e+000 3.00000000e+000 4.00000000e+000]
[ 1.79769313e+308 6.00000000e+000 7.00000000e+000 -1.79769313e+308]
[ 9.00000000e+000 -1.79769313e+308 1.00000000e+001 0.00000000e+000]]

如果要将 nan 和 inf 替换成特定的值,则可以用以下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> import numpy as np
>>> a = np.array([[1, np.nan, 3, 4], [np.inf, 6, 7, -np.inf], [9 ,-np.inf, 10, np.nan]])
>>> print(a)
[[ 1. nan 3. 4.]
[ inf 6. 7. -inf]
[ 9. -inf 10. nan]]
>>> loc_nan = np.isnan(a)
>>> loc_inf = np.isinf(a)
>>> a[loc_nan] = 111
>>> a[loc_inf] = 222
>>> print(a)
[[ 1. 111. 3. 4.]
[222. 6. 7. 222.]
[ 9. 222. 10. 111.]]

【2x00】NumPy 索引

【2x01】获取具体元素

NumPy 的索引和 Python 列表的索引类似,可以通过中括号指定索引获取第 i 个值(从 0 开始计数):

1
2
3
4
5
6
7
8
9
10
>>> import numpy as np
>>> a = np.array([1, 2, 3, 4])
>>> print(a[0])
1
>>> print(a[2])
3
>>> print(a[-1])
4
>>> print(a[-2])
3

在多维数组中,可以用逗号分隔的索引元组获取具体某个元素:

1
2
3
4
5
6
7
8
9
10
>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> print(a)
[[1 2 3]
[4 5 6]
[7 8 9]]
>>> print(a[1, 2])
6
>>> print(a[0, -2])
2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> a = np.array([[[1,2,3,4], [5,6,7,8]], [[9,10,11,12], [13,14,15,16]], [[17,18,19,20], [21,22,23,24]]])
>>> print(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]]]
>>> print(a[0, 1, 2])
7
>>> print(a[1, 0, -1])
12

【2x02】获取行或列

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
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
>>> print(a)
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
>>> print(a[1]) # 取一整行
[4 5 6]
>>> print(a[1, :]) # 取一整行,效果同上
[4 5 6]
>>> print(a[1, ...]) # 取一整行,效果同上
[4 5 6]
>>> print(a[:, 2]) # 取一整列
[ 3 6 9 12]
>>> print(a[..., 2]) # 取一整列,效果同上
[ 3 6 9 12]
>>> print(a[1:3]) # 取多行
[[4 5 6]
[7 8 9]]
>>> print(a[:, 0:2]) # 取多列
[[ 1 2]
[ 4 5]
[ 7 8]
[10 11]]
>>> print(a[[1, 3], :]) # 取第一、三行和所有列
[[ 4 5 6]
[10 11 12]]
>>> print(a[:, [0, 2]]) # 取第零、二列和所有行
[[ 1 3]
[ 4 6]
[ 7 9]
[10 12]]

【2x03】布尔索引

除了直接获取元素以外,还可以通过一个布尔数组来索引目标数组,即通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。

以下实例将筛选出大于 6 的元素:

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

以下实例使用取补运算符 ~ 来过滤掉 inf:

1
2
3
4
5
6
>>> import numpy as np
>>> a = np.array([1, 2, np.inf, 3, -np.inf, 4, 5])
>>> print(a)
[ 1. 2. inf 3. -inf 4. 5.]
>>> print(a[~np.isinf(a)])
[1. 2. 3. 4. 5.]

【2x04】花式索引

花式索引:传递一个索引数组来一次性获得多个数组元素,花式索引总是将数据复制到新数组中。

花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素;如果目标是二维数组,那么就是对应下标的行。

花式索引结果的形状与索引数组的形状一致,而不是与被索引数组的形状一致。

一维数组中的应用:

1
2
3
4
>>> import numpy as np
>>> a = np.array([1, 2, 3, 4, 5, 6])
>>> print([a[0], a[2], a[-1]])
[1, 3, 6]
1
2
3
4
5
>>> import numpy as np
>>> a = np.array([1, 2, 3, 4, 5, 6])
>>> ind = [0, 2, -1]
>>> print(a[ind])
[1 3 6]

二维数组中的应用:

1
2
3
4
5
6
7
8
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
>>> print(a)
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
>>> print([a[0, 1], a[1, 2], a[2, 3]])
[2, 7, 12]
1
2
3
4
5
6
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
>>> row = np.array([0, 1, 2]) # 行
>>> col = np.array([1, 2, 3]) # 列
>>> print(a[row, col])
[ 2 7 12]

【3x00】NumPy 切片

Ndarray 数组对象基于 0 - n 的下标进行索引,与 Python 中列表的切片操作一样,NumPy 的切片也可以通过冒号分隔切片参数 [start:stop:step] 来进行切片操作,另外,NumPy 也提供了一个内置函数 slice(start, stop, step) 来进行切片操作。

slice 方法应用:

1
2
3
4
5
6
7
>>> import numpy as np
>>> a = np.arange(10)
>>> print(a)
[0 1 2 3 4 5 6 7 8 9]
>>> b = slice(2, 8, 2) # 从索引 2 开始到索引 8 停止,步长为 2
>>> print(a[b])
[2 4 6]

通过冒号分隔切片参数 [start:stop:step] 来进行切片:

1
2
3
4
5
6
7
8
>>> import numpy as np
>>> a = np.arange(12)
>>> print(a)
[ 0 1 2 3 4 5 6 7 8 9 10 11]
>>> print(a[1:9:2]) # 从索引 1 开始到索引 9 停止,步长为 2
[1 3 5 7]
>>> print(a[5:])
[ 5 6 7 8 9 10 11] # 从索引 5 开始一直到最后一个元素

二数组中的切片,格式类似于 a[start:stop:step, start:stop:step],以逗号来分割行与列。

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
>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8 ,9], [10, 11, 12], [13, 14, 15], [16, 17, 18]])
>>> print(a)
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]
[13 14 15]
[16 17 18]]
>>> print(a[0:4:2]) # 按照行从索引 0 开始到索引 4 停止,步长为 2
[[1 2 3]
[7 8 9]]
>>> print(a[0:4:2,...]) # 与上述方法相同,... 与 : 作用相同
[[1 2 3]
[7 8 9]]
>>> print(a[...,1:]) # 按照列从索引 1 开始一直到最后一个元素
[[ 2 3]
[ 5 6]
[ 8 9]
[11 12]
[14 15]
[17 18]]
>>> print(a[1:5:2,1:]) # 分别按照行从索引 1 开始到索引 5 停止,步长为 2,按照列从索引 1 开始一直到最后一个元素
[[ 5 6]
[11 12]]

三数组中的切片,格式类似于 a[start:stop:step, start:stop:step, start:stop:step],以逗号来分割块、行与列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> import numpy as np
>>> a = np.array([[[1,2,3,4], [5,6,7,8]], [[9,10,11,12], [13,14,15,16]], [[17,18,19,20], [21,22,23,24]]])
>>> print(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]]]
>>> print(a[1,:,0:2]) # 取索引为 1 的块数、所有行、索引为 0 到 2 的列
[[ 9 10]
[13 14]]
>>> print(a[1,:,:]) # 取索引为 1 的块数、所有行与列
[[ 9 10 11 12]
[13 14 15 16]]
>>> print(a[1,...,:]) # ... 与 : 作用相同
[[ 9 10 11 12]
[13 14 15 16]]

【4x00】NumPy 数组运算以及广播原则

NumPy 数组与数之间、数组与数组之间都支持加减乘除的计算。

  • 对于数组与数之间的计算,由于 NumPy 的广播机制,加减乘除都会对数组的每一个元素进行操作。

  • 对于数组与数组之间的计算,相同维度的,相同位置元素之间会进行计算,不同维度的,将自动触发广播机制。

广播(Broadcast)原则:如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符,或其中的一方的长度为 1,则认为它们是广播兼容的。广播会在缺失和(或)长度为 1 的维度上进行。

通俗理解,以下情况的两个数组均可进行广播:

1、两个数组各维度大小从后往前比对均一致:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
>>> import numpy as np
>>> a = np.ones((3, 4, 5))
>>> b = np.ones((4, 5))
>>> print((a+b).shape)
(3, 4, 5)
>>>
>>>
>>> c = np.ones((3))
>>> d = np.ones((2, 3))
>>> print((c+d).shape)
(2, 3)
>>>
>>>
>>> e = np.ones((3, 4, 5))
>>> f = np.ones((4, 2))
>>> print((e+f).shape)
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
print((e+f).shape)
ValueError: operands could not be broadcast together with shapes (3,4,5) (4,2)
# 因为 e 和 f 维度大小此前往后对比不一致,所以会抛出异常
2、两个数组存在一些维度大小不相等时,在其中一个数组中,这个不相等的维度大小为 1:
1
2
3
4
5
6
>>> import numpy as np
>>> a = np.ones((3, 4, 5))
>>> b = np.ones((4, 1))
>>> print((a+b).shape)
(3, 4, 5)
# 此时虽然 a 与 b 的维度大小此前往后对比不一致,但是 b 数组的这个维度大小为 1,所以仍然可以相加

那么当两个数组之间可以进行广播的时候,具体是怎样广播、怎样计算的呢?以下通过代码和图解来更进一步理解广播机制:

数组与数之间的运算:
1
2
3
4
5
6
7
8
9
10
11
12
>>> import numpy as np
>>> a = np.array([1, 2, 3, 4, 5])
>>> print(a)
[1 2 3 4 5]
>>> print(a+1) # 对数组每一个元素都 +1
[2 3 4 5 6]
>>> print(a-1) # 对数组每一个元素都 -1
[0 1 2 3 4]
>>> print(a*2) # 对数组每一个元素都 *1
[ 2 4 6 8 10]
>>> print(a/2) # 对数组每一个元素都 /1
[0.5 1. 1.5 2. 2.5]
相同维度的数组与数组之间的运算:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> b = np.array([[11, 12, 13, 14, 15], [16, 17, 18, 19, 20]])
>>> print(a)
[[ 1 2 3 4 5]
[ 6 7 8 9 10]]
>>> print(b)
[[11 12 13 14 15]
[16 17 18 19 20]]
>>> print(a+b)
[[12 14 16 18 20]
[22 24 26 28 30]]
>>> print(b-a)
[[10 10 10 10 10]
[10 10 10 10 10]]
>>> print(a*b)
[[ 11 24 39 56 75]
[ 96 119 144 171 200]]
>>> print(b/a)
[[11. 6. 4.33333333 3.5 3. ]
[ 2.66666667 2.42857143 2.25 2.11111111 2. ]]
不同维度的数组与数组之间的运算:

实例一:一个二维数组与一个一维数组相加,此时就会触发广播机制,代码与图解如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
>>> b = np.array([20, 20, 20])
>>> print(a)
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
>>> print(b)
[20 20 20]
>>> print(a+b)
[[21 22 23]
[24 25 26]
[27 28 29]
[30 31 32]]

01

实例二:一个 4 行 3 列的二维数组与一个 4 行 1 列的二维数组相加,此时就会触发广播机制,代码与图解如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
>>> b = np.array([[1], [2], [3], [4]])
>>> print(a)
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
>>> print(b)
[[1]
[2]
[3]
[4]]
>>> print(a+b)
[[ 2 3 4]
[ 6 7 8]
[10 11 12]
[14 15 16]]

02

实例三:一个 3 块 4 行 2 列,即 shape=(3, 4, 2) 的三维数组与一个 1 块 4 行 2 列,即 shape=(1, 4, 2) 的三维数组相加,此时就会触发广播机制,代码与图解如下:

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
>>> import numpy as np
>>> a = np.array([[[1, 2], [3, 4], [5, 6], [7, 8]], [[9, 10], [11, 12], [13, 14], [15, 16]], [[17, 18], [19, 20], [21, 22], [23, 24]]])
>>> b = np.array([[[1, 2], [3, 4], [5, 6], [7, 8]]])
>>> print(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]]]
>>> print(b)
[[[1 2]
[3 4]
[5 6]
[7 8]]]
>>> print(a.shape)
(3, 4, 2)
>>> print(b.shape)
(1, 4, 2)
>>> print(a+b)
[[[ 2 4]
[ 6 8]
[10 12]
[14 16]]

[[10 12]
[14 16]
[18 20]
[22 24]]

[[18 20]
[22 24]
[26 28]
[30 32]]]

03

1
2
3
4
5
这里是一段防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 TRHX。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/104988137
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!

【5x00】数组的拼接与元素的添加

【5x01】将数组转换成列表,拼接完成再转换成数组

数组的拼接,可以先将数组转成列表,利用列表的拼接函数,如:append()、extend() 等进行拼接处理,然后再将列表转成数组即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5, 6])
>>> a_list = list(a)
>>> b_list = list(b)
>>> for i in b_list:
a_list.append(i)


>>> a_list
[1, 2, 3, 4, 5, 6]
>>> a = np.array(a_list)
>>> a
array([1, 2, 3, 4, 5, 6])

【5x02】numpy.append()

numpy.append() 方法可以将一个数组附加到另一个数组的尾部,与 Python 列表中的 append 方法类似,仅支持两个数组之间的拼接,不能一次性拼接多个数组。

基本语法:numpy.append(a, values, axis=None)

参数解释:

参数 描述
a 被添加元素的目标数组
values 要添加元素的目标数组,即将该数组添加到 a 数组的尾部
如果指定了 axis 的值,则要求该数组的维度必须与 a 相同
axis 指定轴,按照指定轴的方向进行拼接
如果未指定轴,则在使用前会将 a 和 values 都展平

应用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5, 6])
>>> print(np.append(a, b)) # 两个一维数组进行拼接
[1 2 3 4 5 6]
>>>
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> b = np.array([10, 11, 12])
>>> print(np.append(a, b)) # 一维数组与二维数组进行拼接
[ 1 2 3 4 5 6 7 8 9 10 11 12]
>>>
>>> a = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
>>> b = np.array([[13, 14, 15], [16, 17, 18]])
>>> print(np.append(a, b)) # 二维数组与三维数组进行拼接
[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18]
>>> print(type(np.append(a, b))) # 拼接后的数组仍然是一个 ndarray 对象
<class 'numpy.ndarray'>

指定 axis 的值举例(指定了 axis 的值,要求两个数组的维度必须相同):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> b = np.array([[7, 8, 9]])
>>> print(np.append(a, b, axis=0)) # a、b 均为二维数组,指定 axis 值为 0
[[1 2 3]
[4 5 6]
[7 8 9]]
>>>
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> b = np.array([7, 8, 9])
>>> print(np.append(a, b, axis=0)) # a 为二维数组,b 为一维数组,指定 axis 值为 0,此时会报错
Traceback (most recent call last):
...
...
ValueError: all the input arrays must have same number of dimensions, ...

【5x03】numpy.concatenate()

numpy.concatenate() 方法能够一次完成多个相同形状数组的拼接。该方法效率更高,适合大规模的数据拼接。

基本语法:numpy.concatenate((a1, a2, ...), axis=0)

参数解释:

参数 描述
a1, a2, … 要拼接的多个数组,要求各数组形状相同
axis 指定轴,按照指定轴的方向进行拼接,默认为 0 轴
要求各数组形状相同举例:如果 axis=0,则要求 1 轴(竖轴)相同,如果 axis=1,则要求 0 轴(横轴)相同。

应用举例:

1
2
3
4
5
6
7
8
9
10
11
>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> b = np.array([[10, 11, 12], [13, 14, 15]])
>>> c = np.array([[16, 17, 18]]) # 三个二维数组的 1 轴(竖轴)相同
>>> print(np.concatenate((a, b, c))) # 三个二维数组默认沿 0 轴(横轴)进行拼接
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]
[13 14 15]
[16 17 18]]


1
2
3
4
5
6
7
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
>>> b = np.array([[9, 10, 11], [12, 13, 14]])
>>> c = np.array([[15, 16], [17, 18]]) # 三个二维数组的 0 轴(横轴)相同
>>> print(np.concatenate((a, b, c), axis=1)) # 三个二维数组沿 1 轴(竖轴)进行拼接
[[ 1 2 3 4 9 10 11 15 16]
[ 5 6 7 8 12 13 14 17 18]]


1
2
3
4
5
6
7
8
9
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
>>> b = np.array([[9, 10, 11], [12, 13, 14]])
>>> c = np.array([[15, 16], [17, 18]]) # 三个二维数组的 0 轴(横轴)相同
>>> print(np.concatenate((a, b, c), axis=0)) # 三个二维数组沿 0 轴(横轴)进行拼接将会报错
Traceback (most recent call last):
...
...
ValueError: all the input array dimensions for the concatenation axis must match exactly, ...


### 【5x04】numpy.stack()
numpy.stack() 方法用于沿新轴连接数组序列。

基本语法:numpy.stack(arrays, axis=0)

参数解释:

| 参数 | 描述 |
| —— | —— |
| arrays | 相同形状的数组序列 |
| axis | 返回数组中的轴,输入数组将沿着该轴来进行堆叠 |

应用举例:

1
2
3
4
5
6
7
8
9
10
>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5, 6])
>>> print(np.stack((a, b),axis=0))
[[1 2 3]
[4 5 6]]
>>> print(np.stack((a, b),axis=1))
[[1 4]
[2 5]
[3 6]]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])
>>> print(np.stack((a,b),axis=0))
[[[1 2]
[3 4]]

[[5 6]
[7 8]]]
>>> print(np.stack((a,b),axis=1))
[[[1 2]
[5 6]]

[[3 4]
[7 8]]]


### 【5x05】numpy.vstack()

numpy.vstack() 方法通过垂直堆叠来生成数组。

基本语法:numpy.vstack(tup)

参数解释:tup:数组序列,如果是一维数组进行堆叠,则数组长度必须相同,其它数组除了第一个轴(axis=0)的长度可以不同外,其它轴的长度必须相同。

应用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5, 6])
>>> print(np.vstack((a,b)))
[[1 2 3]
[4 5 6]]
>>>
>>> b = np.array([4, 5])
>>> print(np.vstack((a,b))) # 一维数组长度不一样时将抛出异常
Traceback (most recent call last):
...
...
ValueError: all the input array dimensions for the concatenation axis must match exactly, ...
1
2
3
4
5
6
7
8
9
10
11
12
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])
>>> a.shape
(2, 2)
>>> b.shape
(2, 2)
>>> print(np.vstack((a,b)))
[[1 2]
[3 4]
[5 6]
[7 8]]
1
2
3
4
5
6
7
8
9
10
11
12
13
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8],[9,10]])
>>> a.shape
(2, 2)
>>> b.shape
(3, 2)
>>> print(np.vstack((a,b))) # 第一个轴(axis=0)可以不同,其它轴必须相同
[[ 1 2]
[ 3 4]
[ 5 6]
[ 7 8]
[ 9 10]]

【5x06】numpy.hstack()

numpy.hstack() 方法通过水平堆叠来生成数组。

基本语法:numpy.hstack(tup)

参数解释:tup:数组序列,除了一维数组的堆叠可以是不同长度外,其它数组堆叠时,除了第二个轴(axis=1)的长度可以不同外,其它轴的长度必须相同。

应用举例:

1
2
3
4
5
>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5])
>>> print(np.hstack((a,b)))
[1 2 3 4 5]
1
2
3
4
5
6
7
8
9
10
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])
>>> a.shape
(2, 2)
>>> b.shape
(2, 2)
>>> print(np.hstack((a,b)))
[[1 2 5 6]
[3 4 7 8]]
1
2
3
4
5
6
7
8
9
10
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6,7],[8,9,10]])
>>> a.shape
(2, 2)
>>> b.shape
(2, 3)
>>> print(np.hstack((a,b))) # 第二个轴(axis=1)可以不同,其它轴必须相同
[[ 1 2 5 6 7]
[ 3 4 8 9 10]]

【5x07】numpy.dstack()

numpy.dstack() 方法会沿着第三个维度拼接数组。

基本语法:numpy.dstack(tup)

参数解释:tup:数组序列,除了第三个轴(axis=2)的长度可以不同外,其它轴的长度必须相同。一维或二维数组必须具有相同的形状。

应用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> import numpy as np
>>> a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
>>> b = np.array([[[9], [10]], [[11], [12]]])
>>> a.shape
(2, 2, 2)
>>> b.shape
(2, 2, 1)
>>> print(np.dstack((a,b))) # a 与 b 的第三个轴(axis=2)一个是 2,另一个是 1,可以不同,但其他轴必须相同
[[[ 1 2 9]
[ 3 4 10]]

[[ 5 6 11]
[ 7 8 12]]]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>> import numpy as np
>>> a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
>>> b = np.array([[[9, 10], [11, 12]]])
>>> a.shape
(2, 2, 2)
>>> b.shape
(1, 2, 2)
>>> print(np.dstack((a,b))) # a 与 b 的第一个轴(axis=0)不同,将会抛出异常
[[[ 1 2 9]
[ 3 4 10]]

[[ 5 6 11]
[ 7 8 12]]]
>>> print(np.dstack((a,b)))
Traceback (most recent call last):
...
...
ValueError: all the input array dimensions for the concatenation axis must match exactly, ...

【5x08】以上几种方法的区别

  • concatenate() 方法在 axis=0 的时候相当于 vstack() 方法;
  • concatenate() 方法在 axis=1 的时候相当于 hstack() 方法;
  • concatenate() 方法在 axis=2 的时候相当于 dstack() 方法;
  • concatenate() 方法不会生成一个新的维度,且数组的维度不一定相同,而 stack() 方法生成一个新的维度,并且要求所有数组形状都要一样。

concatenate() 方法与 stack() 方法比较:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5, 6])
>>> c = np.stack((a, b), axis=0)
>>> d = np.concatenate((a, b), axis=0)
>>> a.shape
(3,)
>>> b.shape
(3,)
>>> c.shape
(2, 3)
>>> d.shape
(6,)
>>> print(c)
[[1 2 3]
[4 5 6]]
>>> print(d)
[1 2 3 4 5 6]

【5x09】numpy.insert()

numpy.insert() 方法沿指定轴在指定索引之前插入值。

基本语法:numpy.insert(arr, obj, values, axis=None)

参数解释:

参数 描述
arr 原数组
obj 索引值,将在其之前插入值
values 要插入的值
axis 轴,将沿着该轴进行插入操作,如果未指定,则插入前,原数组会被展开,变为一维数组

应用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> import numpy as np
>>> a = np.array([[1,2],[3,4],[5,6]])
>>> print(np.insert(a, 3, [0, 0])) # 未指定 axis 参数,在插入之前原数组会被展开
[1 2 3 0 0 4 5 6]
>>> print(np.insert(a, 1, [0], axis = 0)) # 沿 0 轴广播插入
[[1 2]
[0 0]
[3 4]
[5 6]]
>>> print(np.insert(a, 1, 11, axis = 1)) # 沿 1 轴广播插入
[[ 1 11 2]
[ 3 11 4]
[ 5 11 6]]

【5x10】numpy.r_

numpy.r_:rrow(行) 的缩写,即按照行连接两个矩阵,要求列数相等。

应用举例:

1
2
3
4
5
6
7
8
9
>>> import numpy as np
>>> a = np.array([[1, 2, 3],[7, 8, 9]])
>>> b = np.array([[4, 5, 6],[1, 2, 3]])
>>>
>>> np.r_[a, b]
array([[1, 2, 3],
[7, 8, 9],
[4, 5, 6],
[1, 2, 3]])

【5x11】numpy.c_

numpy.c_:ccolumn(列) 的缩写,即按照列连接两个矩阵,要求行数相等。

应用举例:

1
2
3
4
5
6
7
>>> import numpy as np
>>> a = np.array([[1, 2, 3],[7, 8, 9]])
>>> b = np.array([[4, 5, 6],[1, 2, 3]])
>>>
>>> np.c_[a, b]
array([[1, 2, 3, 4, 5, 6],
[7, 8, 9, 1, 2, 3]])

【6x00】数组的分割与元素的删除

【6x01】numpy.split()

numpy.split() 方法可以沿特定的轴将数组均等的分割为子数组。如果不能等分,将抛出异常。

基本语法:numpy.split(ary, indices_or_sections, axis=0)

参数解释:

参数 描述
ary 被分割的数组
indices_or_sections 如果是一个整数 N,则该数组将沿 axis 均分为 N 个数组
如果是一维整数数组,则数组元素代表每个分割点位置(左闭右开),N 个分裂点会得到 N + 1 个子数组
axis 沿着哪个维度进行分割,默认为 0,横向分割;为 1 时,纵向分割

应用举例:

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
>>> import numpy as np
>>> a = np.arange(10)
>>> print(a)
[0 1 2 3 4 5 6 7 8 9]
>>> print(np.split(a, 5)) # 将数组分为五个大小相等的子数组
[array([0, 1]),
array([2, 3]),
array([4, 5]),
array([6, 7]),
array([8, 9])]
>>>
>>> print(np.split(a, 4)) # 无法等分的情况下将抛出异常
Traceback (most recent call last):
...
...
ValueError: array split does not result in an equal division
>>>
>>> print(np.split(a, [4, 8])) # 分割点为索引 4 和 8 的位置,相当于 a[:4]、a[4:8]、a[8:]
[array([0, 1, 2, 3]),
array([4, 5, 6, 7]),
array([8, 9])]
>>>
>>> a = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> print(np.split(a, 5, axis=1)) # 指定 axis=1,按照纵向分割数组
[array([[1],
[6]]),
array([[2],
[7]]),
array([[3],
[8]]),
array([[4],
[9]]),
array([[ 5],
[10]])]

【6x02】numpy.array_split()

numpy.array_split() 的用法和作用都与 split() 方法一致,都可以用一个整数或者整数列表来分割数组。

两者的区别:如果输入的是一个 int 类型的数字,那么在 split() 方法中,数组必须是均等的分割,否则就会报错,而在 array_split() 方法中是可以进行不均等的分割的。

基本语法:numpy.array_split(ary, indices_or_sections, axis=0)

参数解释:

参数 描述
ary 被分割的数组
indices_or_sections 如果是一个整数 N,则该数组将沿 axis 分割为 N 个数组,可以不是均分的
如果是一维整数数组,则数组元素代表每个分割点位置(左闭右开),N 个分裂点会得到 N + 1 个子数组
axis 沿着哪个维度进行分割,默认为 0,横向分割;为 1 时,纵向分割

应用举例:

1
2
3
4
5
6
7
>>> import numpy as np
>>> a = np.array([1, 2, 3, 4, 5, 6, 7])
>>> print(np.array_split(a, 3))
[array([1, 2, 3]), array([4, 5]), array([6, 7])] # 可以是不均分的
>>>
>>> print(np.array_split(a, 4))
[array([1, 2]), array([3, 4]), array([5, 6]), array([7])]

【6x03】numpy.vsplit()

numpy.vsplit() 方法相当于 split() 方法在 axis=0 时的效果,即横向分割数组。

基本语法:numpy.vsplit(ary, indices_or_sections)

参数解释:

参数 描述
ary 被分割的数组
indices_or_sections 如果是一个整数 N,则该数组将沿 axis 分为 N 个相等的数组
如果是一维整数数组,则数组元素代表每个分割点位置(左闭右开),N 个分裂点会得到 N + 1 个子数组

应用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
>>> print(np.vsplit(a, 2))
[array([[1, 2, 3],
[4, 5, 6]]),
array([[ 7, 8, 9],
[10, 11, 12]])]
>>>
>>> print(np.vsplit(a, [1, 3]))
[array([[1, 2, 3]]),
array([[4, 5, 6],
[7, 8, 9]]),
array([[10, 11, 12]])]

【6x04】numpy.hsplit()

numpy.hsplit() 方法相当于 split() 方法在 axis=1 时的效果,即纵向分割数组。

基本语法:numpy.hsplit(ary, indices_or_sections)

参数解释:

参数 描述
ary 被分割的数组
indices_or_sections 如果是一个整数 N,则该数组将沿 axis 分为 N 个相等的数组
如果是一维整数数组,则数组元素代表每个分割点位置(左闭右开),N 个分裂点会得到 N + 1 个子数组

应用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> print(np.hsplit(a, 5))
[array([[1],
[6]]),
array([[2],
[7]]),
array([[3],
[8]]),
array([[4],
[9]]),
array([[ 5],
[10]])]
>>>
>>> print(np.hsplit(a, [1, 3]))
[array([[1],
[6]]),
array([[2, 3],
[7, 8]]),
array([[ 4, 5],
[ 9, 10]])]

【6x05】numpy.dsplit()

numpy.dsplit() 方法相当于 split() 方法在 axis=2 时的效果,即沿第三轴将数组拆分为多个子数组。

基本语法:numpy.dsplit(ary, indices_or_sections)

参数解释:

参数 描述
ary 被分割的数组
indices_or_sections 如果是一个整数 N,则该数组将沿 axis 分为 N 个相等的数组
如果是一维整数数组,则数组元素代表每个分割点位置(左闭右开),N 个分裂点会得到 N + 1 个子数组

应用举例:

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
>>> import numpy as np
>>> a = np.arange(16).reshape(2, 2, 4)
>>> print(a)
[[[ 0 1 2 3]
[ 4 5 6 7]]

[[ 8 9 10 11]
[12 13 14 15]]]
>>> print(np.dsplit(a, 2))
[array([[[ 0, 1],
[ 4, 5]],
[[ 8, 9],
[12, 13]]]),
array([[[ 2, 3],
[ 6, 7]],
[[10, 11],
[14, 15]]])]
>>>
>>> print(np.dsplit(a, [3, 6]))
[array([[[ 0, 1, 2],
[ 4, 5, 6]],
[[ 8, 9, 10],
[12, 13, 14]]]),
array([[[ 3],
[ 7]],
[[11],
[15]]]),
array([], shape=(2, 2, 0), dtype=int32)]

【6x06】numpy.delete()

numpy.delete() 方法返回一个从原数组中删除了指定子数组的新数组。

基本语法:numpy.delete(arr,obj,axis=None)

参数解释:

参数 描述
arr 原数组
obj 可以是切片、整数或整数数组形式,表示沿指定轴删除的子数组的索引
当 obj 为切片形式时,要用 np.s_[:] 的格式
axis 轴,将沿着该轴进行插入操作,如果未指定,则插入前,原数组会被展开,变为一维数组

应用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
>>> print(np.delete(a, 8)) # 未指定 axis 参数,在插入之前原数组会被展开,然后再删除索引为 8 的元素
[ 1 2 3 4 5 6 7 8 10 11 12]
>>>
>>> print(np.delete(a, 1, axis=0)) # 指定 axis=0,删除索引值为 1 即第二行
[[ 1 2 3 4]
[ 9 10 11 12]]
>>>
>>> print(np.delete(a, 1, axis=1)) # 指定 axis=1,删除索引值为 1 即第二列
[[ 1 3 4]
[ 5 7 8]
[ 9 11 12]]
>>>
>>> print(np.delete(a, np.s_[:2], axis=1)) # 切片形式,删除前两列
[[ 3 4]
[ 7 8]
[11 12]]
>>>
>>> print(np.delete(a, [0, 2], axis=1)) # 数组形式,删除索引值为 0 和 2 的列
[[ 2 4]
[ 6 8]
[10 12]]

【6x07】numpy.unique()

numpy.unique() 方法用于去除数组中的重复元素。

基本语法:numpy.unique(arr, return_index=False, return_inverse=False, return_counts=False, axis=None)

参数解释:

参数 描述
arr 原数组,如果不是一维数组则会被展开为一维数组
return_index 如果为 true,则返回新列表元素在旧列表中的位置(下标),并以列表形式储
return_inverse 如果为 true,则返回旧列表元素在新列表中的位置(下标),并以列表形式储
return_counts 如果为 true,则返回去重数组中的元素在原数组中的出现次数
axis 指定轴

应用举例:

未指定 axis 值,原数组将会被展开:

1
2
3
4
5
6
7
>>> import numpy as np
>>> a = np.array([1, 1, 2, 2, 3, 4, 5, 5])
>>> b = np.array([[1, 1], [2, 3], [3, 4]])
>>> print(np.unique(a))
[1 2 3 4 5]
>>> print(np.unique(b))
[1 2 3 4]

指定 axis 值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> import numpy as np
>>> a = np.array([[1, 0, 1], [1, 0, 1], [2, 3, 2], [5, 6, 5]])
>>> print(a)
[[1 0 1]
[1 0 1]
[2 3 2]
[5 6 5]]
>>> print(np.unique(a, axis=0)) # 删除相同的行
[[1 0 1]
[2 3 2]
[5 6 5]]
>>> print(np.unique(a, axis=1)) # 删除相同的列
[[0 1]
[0 1]
[3 2]
[6 5]]

return_counts 为 True 时,返回去重数组中的元素在原数组中的出现次数:

1
2
3
4
5
>>> import numpy as np
>>> a = np.array([1, 1, 1, 2, 2, 3, 4, 5, 5])
>>> print(np.unique(a, return_counts=True))
(array([1, 2, 3, 4, 5]), array([3, 2, 1, 1, 2], dtype=int64))
# 前一个 array 表示去重后的数组,后一个 array 表示每一个元素在原数组中出现的次数

1
2
3
4
5
这里是一段防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 TRHX。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/104988137
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!


您的喜欢是作者写作最大的动力!❤️
  • PayPal
  • AliPay
  • WeChatPay
  • QQPay
Donate

 评论


Copyright 2018-2020 TRHX'S BLOG ICP 鄂ICP备19003281号-4MOE ICP 萌ICP备20202022号 正在载入... 百度统计

UV
PV
WordCount288.9k