Python进阶-Numpy科学计算库(简单入门)

Numpy简介

NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

NumPy 的前身 Numeric 最早是由 Jim Hugunin 与其它协作者共同开发,2005 年,Travis Oliphant 在 Numeric 中结合了另一个同性质的程序库 Numarray 的特色,并加入了其它扩展而开发了 NumPy。NumPy 为开放源代码并且由许多协作者共同维护开发。


安装

因为我使用的是python3,因此需要自己手动来安装Numpy

pip3 install numpy

一般来说这条命令就可以安装成功了
如果失败的话可能是因为权限的问题可以尝试在命令前加一个’sudo’,即

sudo pip3 install numpy

然后按照提示输入密码就可以了

success

现在numpy就安装成功了
首先对将numpy引入

1
import numpy as np   # np就相当于numpy的别名了

基础的属性

创建一个矩阵的语法为

1
name = np.array([[...]...])

例如,要创建一个3x1的矩阵,矩阵名为array

1
2
3
4
array = np.array([[123],[456],[789]])

# 3x3矩阵的建立方法
array = np.array([[1,2,3],[4,5,6],[7,8,9]])

打印出来看下

1
2
3
4
>>> print(array)
[[123]
[456]
[789]]

其他的一些简单的属性

1
2
3
4
5
6
7
8
>>> print(array.ndim)   # 矩阵的维度
2
>>> print(array.shape) # 矩阵的形状
(3, 1)
>>> print(array.size) # 矩阵的大小(元素个数)
3
>>> print(array.dtype) # 矩阵中元素类型
int64

创建array

在创建的同时声明元素类型

使用上文中的方法的话,我们并没有办法制定元素的类型,因此我们可以通过在创建时声明元素类型来解决这个问题

1
2
a = np.array([1,2,3],dtype = np.int32)
b = np.array([2,3,4],dtype = np.float)

特殊矩阵

如果我们需要一个元素全为0的矩阵的话,可以使用numpy中的zeros()

1
2
3
4
>>> zero = np.zeros((2,3))   # 创建一个2x3的零矩阵
>>> print(zero)
[[0,0,0]
[0,0,0]]

同理,我们还可以生成全为1的制定大小的矩阵

1
one = np.ones(3,4)

empty矩阵

1
2
3
4
>>> empty = np.empty((2,3))   
>>> print(empty)
[[0,0,0]
[0,0,0]]

​ 需要注意的是empty所创建出来的矩阵所有元素都不为0,但是非常接近于0.
​ 因此在我们需要使用一个矩阵来除以empty矩阵的时候,就不会出错了。反之,除以zero矩阵的话就不对了。

生成矩阵的其他方法

arange

1
2
3
4
5
6
7
8
9
>>> c = np.arange(10)   # 生成一个0到9的一维矩阵
>>> print(c)
[0 1 2 3 4 5 6 7 8 9]
>>> d = np.arange(4,12) # 生成一个[4,12)的一维矩阵
>>> print(d)
[4 5 6 7 8 9 10 11]
>>> e = np.arange(1,20,3) # [1,20) 间隔为3
>>> print(e)
[1 4 7 10 13 16 19]

rashap 重新定义矩阵的形状

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

矩阵的运算1

简单的运算

​ 简单的加、减、乘、除、取余、取整、阶乘等运算方式都是按位置1对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
35
36
37
>>> arr1 = np.array([[1,2,3],[4,5,6]])
>>> arr2 = np.array([[1,1,2],[2,3,3]])
>>> print(arr1)
[[1 2 3]
[4 5 6]]
>>> print(arr2)
[[1 1 2]
[2 3 3]]
>>> print(arr1+arr2) # 加法
[[2 3 5]
[6 8 9]]
>>> print(arr1-arr2) # 减法
[[0 1 1]
[2 2 3]]
>>> print(arr1*arr2) # 乘法
[[ 1 2 6]
[ 8 15 18]]
>>> print(arr1**arr2) # 阶乘
[[ 1 2 9]
[ 16 125 216]]
>>> print(arr1/arr2) # 除法
[[1. 2. 1.5 ]
[2. 1.66666667 2. ]]
>>> print(arr1%arr2) # 取余
[[0 0 1]
[0 2 0]]
>>> print(arr1//arr2) # 取整
[[1 2 1]
[2 1 2]]
>>> print(arr1+1) # 所有元素都加一个数
[[2 3 4]
[5 6 7]]
# 减法、乘法、除法等也一样
>>> arr3 = arr1 > 3 # 比较判断
>>> print(arr3)
[[False False False]
[ True True True]]

矩阵的运算

​ 矩阵间的运算规则与线代中的方法相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> arr4 = np.ones((3,5))     # 定义一个元素全为1的矩阵
>>> np.dot(arr1,arr4) # 矩阵arr1与arr4相乘
array([[ 6., 6., 6., 6., 6.],
[15., 15., 15., 15., 15.]])
>>> arr1.dot(arr4) # 同上
array([[ 6., 6., 6., 6., 6.],
[15., 15., 15., 15., 15.]])
>>> print(arr1.T) # 转置矩阵
[[1 4]
[2 5]
[3 6]]
>>> print(np.transpose(arr1)) # 同上
[[1 4]
[2 5]
[3 6]]

随机数的生成以及矩阵的运算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
43
44
45
46
47
48
49
50
51
52
53
54
# 生成3x2的在0-1之间的随机数
>>> sample1 = np.random.random((3,2))
>>> print(sample1)
[[0.59323399 0.16406566]
[0.53314295 0.42851363]
[0.06050496 0.50214404]]
# 生成3x2的符合标准正态分布的随机数
>>> sample2 = np.random.normal(size=(3,2))
>>> print(sample2)
[[-0.90205973 -0.08097247]
[ 1.72986545 -0.81119537]
[-0.40989374 0.27041087]]
# 生成3x2的0-10之间的整数随机数
>>> sample3 = np.random.randint(0,10,size=(3,2))
>>> print(sample3)
[[6 2]
[9 6]
[0 3]]
# 求和
>>> np.sum(sample1)
2.281605244421956
# 求最小值 max同理
>>> np.min(sample1)
0.06050496121103843
# axis = 0 对列求和
# axis = 1 对行求和
>>> np.sum(sample1,axis = 0)
array([1.18688191, 1.09472334])
>>> np.sum(sample1,axis = 1)
array([0.75729965, 0.96165658, 0.562649 ])
# 求最大值最小值索引
>>> np.argmax(sample1)
>>> np.argmin(sample1)
# 求平均值
>>> print(np.mean(sample1))
>>> print(sample1.mean())
# 求中位数
>>> np.median(sample1)
# 求开方的结果
>>> np.sqrt(sample1)
# 排序
>>> sample4 = np.random.randint(0,10,size=(1,10))
>>> print(sample4)
[[6 6 2 5 6 1 0 2 7 6]]
>>> np.sort(sample4)
array([[0, 1, 2, 2, 5, 6, 6, 6, 6, 7]])
# 如果是多维的话,则会对每一行进行排序
>>> np.sort(sample1)
array([[0.16406566, 0.59323399],
[0.42851363, 0.53314295],
[0.06050496, 0.50214404]])
# sample4中的元素小于2的会变成2,大于7的会变成7
>>> np.clip(sample4,3,7)
array([[6, 6, 3, 5, 6, 3, 3, 3, 7, 6]])

numpy的索引

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
48
>>> arr1 = np.arange(2,14)
>>> print(arr1)
[ 2 3 4 5 6 7 8 9 10 11 12 13]
>>> print(arr1[2]) # 第二个位置的数据
4
# 个人感觉和数组很像(小声BB,下边的内容还没看
>>> print(arr1[1:4]) # [1,4)的数据
[3 4 5]
# 最后一个位置为-1
>>> print(arr1[2:-1]) # [2,-1)的数据
[ 4 5 6 7 8 9 10 11 12]
# 空着的话默认从最两侧的位置开始
>>> print(arr1[:5])
[2 3 4 5 6]
>>> print(arr1[-2:])
[12 13]
>>> arr2 = arr1.reshape(3,4)
# (像二维数组~~~
>>> print(arr2)
[[ 2 3 4 5]
[ 6 7 8 9]
[10 11 12 13]]
>>> print(arr2[1])
[6 7 8 9]
>>> print(arr2[1][1])
7
>>> print(arr2[1,1])
7
>>> print(arr2[:,2]) # 提取所有的行的第二列
[ 4 8 12]
>>> for i in arr2: # 循环,迭代行
... print(i)
[2 3 4 5]
[6 7 8 9]
[10 11 12 13]
>>> for i in arr2.T: # 使用转置,迭代列
... print(i)
[ 2 6 10]
[ 3 7 11]
[ 4 8 12]
[ 5 9 13]
>>> for i in arr2.flat: # 迭代元素
... print(i)
2
3
...
12
13

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# 垂直合并
>>> arr1 = np.array([1,2,3])
>>> arr2 = np.array([4,5,6])
>>> arr3 = np.vstack((arr1,arr2))
>>> print(arr3)
[[1 2 3]
[4 5 6]]
>>> print(arr3.shape)
(2, 3)
# 水平合并
>>> arr4 = np.hstack((arr1,arr2))
>>> print(arr4)
[1 2 3 4 5 6]
>>> print(arr4.shape)
(6,)
>>> arrv = np.vstack((arr1,arr2,arr3))
# 合并多行/列
>>> print(arrv)
[[1 2 3]
[4 5 6]
[1 2 3]
[4 5 6]]
>>> arrh = np.hstack((arr1,arr2,arr4))
>>> print(arrh)
[1 2 3 4 5 6 1 2 3 4 5 6]
# 使用参数控制按行/列合并
# axis = 0 垂直合并 (合并的array维度要相同,形状要匹配)
# axis = 1 水平合并 (合并的array维度要相同,形状要匹配)
>>> arr = np.concatenate((arr3,arrv),axis=0)
>>> print(arr)
[[1 2 3]
[4 5 6]
[1 2 3]
[4 5 6]
[1 2 3]
[4 5 6]]
# 一维的array不能转置
>>> print(arr1)
[1 2 3]
>>> print(arr1.T)
[1 2 3]
# 增加维度
# 注意newaxis的位置
>>> print(arr1.shape)
(3,)
>>> arr1_1 = arr1[np.newaxis,:]
>>> print(arr1_1)
[[1 2 3]]
>>> print(arr1_1.shape)
(1, 3)
>>> print(arr1_1.T) # 转置
[[1]
[2]
[3]]
>>> arr1_2 = arr1[:,np.newaxis]
>>> print(arr1_2)
[[1]
[2]
[3]]
>>> print(arr1_2.shape)
(3, 1)
# atleast_xd 变为x维的矩阵
>>> arr1_3 = np.atleast_2d(arr1)
>>> print(arr1_3)
[[1 2 3]]
>>> print(arr1_3.T)
[[1]
[2]
[3]]

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
>>> arr1 = np.arange(12).reshape(3,4)
>>> print(arr1)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
# 将arr1分割
# axis = 1 水平方向切割
>>> arr2,arr3 = np.split(arr1,2,axis=1)
# arr2,arr3 = np.hsplit(arr1,2)
>>> print(arr2)
[[0 1]
[4 5]
[8 9]]
>>> print(arr3)
[[ 2 3]
[ 6 7]
[10 11]]
# axis = 0 垂直方向分割
>>> arr4,arr5,arr6 = np.split(arr1,3,axis=0)
# arr4,arr5,arr6 = np.vsplit(arr1,3)
>>> print(arr4)
[[0 1 2 3]]
>>> print(arr5)
[[4 5 6 7]]
>>> print(arr6)
[[ 8 9 10 11]]
# 不等分切割
>>> arr2,arr3,arr4 = np.array_split(arr1,3,axis=1)
>>> print(arr2)
[[0 1]
[4 5]
[8 9]]
>>> print(arr3)
[[ 2]
[ 6]
[10]]
>>> print(arr4)
[[ 3]
[ 7]
[11]]

numpy的浅拷贝和深拷贝

1
2
3
4
5
6
7
8
9
# 个人理解:类似于指针和形参
# 浅拷贝:指针
# 深拷贝:形参

# 浅拷贝
arr2 = arr1

#深拷贝
arr2 = arr1.copy()