1 什么是Numpy?
一种支持数学高维度和矩阵计算的python包,集成在Anaconda中。
numpy 中最基本的元素是N维数组(N dimension array,ndarray)。因此后面的所有操作都是围绕着如何针对 N 维数组进行操作的。
2 Numpy 基本定义
2.1 初始化操作
import numpy as np
#### numpy的初始化,这两种方式都可以
array = np.array([[1,2,3],[4,5,6]])
b = np.array((1,2,3))
print(array, b) # 注意元组不能直接写==来判断是否相等,它仅支持用真值
#### numpy的几种属性
print("维度:" , array.ndim) #维度: 2
print("行数和列数",array.shape) #行数和列数:(2,3)
print("大小:",array.size) #大小:6
#### 指定数据
a = np.array([2 , 23 , 4] , dtype = np.int)
print("a 的数据类型:" , a.dtype) # a 的数据类型: int32
b = np.array([2 , 23 , 4] , dtype = np.int32)
print("b 的数据类型:" , b.dtype) # b 的数据类型: int32
c = np.array([2 , 23 , 4] , dtype = np.float)
print("c 的数据类型:", c.dtype) # c 的数据类型: float64
d = np.array([2 , 23 , 4] , dtype = np.float32)
print("d 的数据类型:", d.dtype) # d 的数据类型: float32
#### 快速创建特定的 ndarray
a = np.zeros((3 , 4))
print("全0矩阵:\n", a.dtype) # 输出的是一个3 * 4 的全0矩阵,dtype默认=float 64
b = np.ones((2 , 3) , dtype = np.int32)
print("全1矩阵:\n", b) # 输出的是一个3 * 4 的全1矩阵
c = np.empty((3 , 4)) # 其实
print("空矩阵:\n", c) # 输出的是一个3 * 4 的每个数值都接近0的随机矩阵
#### 连续数组
a = np.arange(10 , 20 , 2) #产生一个 10 - 19的数组, 步长为2
print("a 的内容", a) # a 的内容 [10 12 14 16 18]
print("a 的形状", a.shape) # a 的形状 (5,)
b = np.arange(12) # 产生一个 0-11的数组, 步长为1
print("b 的内容", b) # b 的内容 [ 0 1 2 3 4 5 6 7 8 9 10 11]
print("b 的形状", b.shape) # b 的形状 (12,)
#### 修改数组形状
b = np.arange(12).reshape((3 , 4)) # 产生一个 0-11的数组, 步长为1
print("b 的内容", b) # b变成了一个 3*4 的矩阵
print("b 的形状", b.shape) # b 的形状 (3,4)
a = np.arange(13).reshape((3 , 4)) # 将一行数据变成一个3*4的其他的都不行
print(a) # 如果不能变的话,会报错:cannot reshape array of size 13 into shape (3,4)
#### 按照步长切分一组数据:用于分割线段
a = np.linspace(1, 10, 20)
print(a)
'''
输出结果:
[ 1. 1.47368421 1.94736842 2.42105263 2.89473684 3.36842105
3.84210526 4.31578947 4.78947368 5.26315789 5.73684211 6.21052632
6.68421053 7.15789474 7.63157895 8.10526316 8.57894737 9.05263158
9.52631579 10. ]
'''
2.2 如何计算维度?
- 如果要说 ndarray 是几维,要从外到内,数有几层括号,有几层就是几维;
- 如果要说 shape,则从外到内,数每层按照逗号分成了几个,有几个就是几个,在括号里填上数字。
- 对于 axis,其实就是 reshape 之后的顺序。按照轴操作,即将数组按照给出的轴进行折叠。(好好理解一下这句话,来源:CSDN)
3 numpy 基础运算
numpy 提供了一系列的基础运算,方便对矩阵进行操作。
3.1 基础运算1
import numpy as np
#### 定义2个矩阵
a = np.array((1, 2, 3))
b = np.array((2, 3, 4))
#### 基本的加减乘除
c = a + b ** 2
print("输出结果:", c) # 输出结果: [ 5 11 19]
d = a * b #对每一项对应乘
print("输出结果:", d) # 输出结果: [ 2 6 12]
e = 10 * np.sin(a) #数学函数工具
print("输出结果:", e) # 输出结果: [8.41470985 9.09297427 1.41120008]
b = np.array((2, 3, 4))
print("输出结果:", b > 3) # 对每一项进行判断, 输出结果: [False False True]
#### 矩阵乘积
a = np.array([[1, 1], [0, 1]])
b = np.arange(4).reshape((2, 2)) # 默认将数据填进去
c_dot = np.dot(a, b)
print("输出结果:\n", c_dot)
'''
输出结果:
[[2 4]
[2 3]]
'''
c_dot2 = a.dot(b) # 换了一种写法,同样的结果
print("输出结果:\n", c_dot2)
'''
输出结果:
[[2 4]
[2 3]]
'''
#### sum(),min(),max()三种脚本,横 1 纵 0
a = np.random.random((2, 4)) # 随机产生一个(0,1)之间的数
print("a 的值为:", a)
'''
a 的值为:
[[0.99808851 0.62665407 0.02439204 0.21796687]
[0.49979296 0.10561328 0.28009502 0.47049305]]
'''
print("对 a 的所有数据按 0 轴求和:", np.sum(a, axis=1)) # axis是轴的意思,axis = 1 按照横轴
# 对 a 的所有数据按横轴求和: [1.86710149 1.3559943 ]
print("对 a 的所有数据按 1 轴求最小值:", np.min(a, axis=0)) # axis = 0 是按纵轴的意思
# 对 a 的所有数据按纵轴求最小值: [0.49979296 0.10561328 0.02439204 0.21796687]
print("对 a 的所有数据找最大值:", np.max(a))
# 对 a 的所有数据找最大值: 0.9980885061479571
这里提供一种手推矩阵的方法。axis 参数用于指定按照哪一项进行折叠。正着数括号,将对应的括号去掉之后,其余的数据不进行变化,对应项加起来就好。举个例子:按照标点符号法进行展开,看的更清楚。
import numpy as np
a = np.arange(12).reshape(3,2,2)
print("a 的值为:\n", a)
'''
a 的值为:
[[[ 0 1]
[ 2 3]]
[[ 4 5]
[ 6 7]]
[[ 8 9]
[10 11]]]
'''
print("对 a 的所有数据按 0 轴求和:\n", np.sum(a, axis=0)) # axis = 0 是按纵轴的意思
'''
对 a 的所有数据按 0 轴求和:
[[12 15]
[18 21]]
'''
print("对 a 的所有数据按 1 轴求和:\n", np.sum(a, axis=1)) # axis是轴的意思,axis = 1按照横轴
'''
对 a 的所有数据按 1 轴求和:
[[ 2 4]
[10 12]
[18 20]]
'''
print("对 a 的所有数据按 2 轴求和:\n", np.sum(a, axis=2)) # axis = 0 是按纵轴的意思
'''
对 a 的所有数据按 2 轴求最和:
[[ 1 5]
[ 9 13]
[17 21]]
'''
3.2 基础运算2
import numpy as np
#### 对应矩阵的最小元素和最大元素索引
a = np.arange(2, 14).reshape((3, 4))
print("最小值索引:", np.argmin(a)) # 最小值索引: 0
print("最大值索引:", np.argmax(a)) # 最大值索引: 11
#### 求平均值
print("平均值:", np.mean(a)) # 平均值: 7.5
print("平均值:", np.average(a)) # 平均值: 7.5
print("平均值:", a.mean()) # 平均值: 7.5
#### 求中位数
print("中位数:", np.median(a)) # 中位数:7.5
#### 对应矩阵的最小元素和最大元素索引
a = np.arange(2, 14).reshape((3, 4))
#### 累加函数:每个元素加到这一项的时候的元素和
print(np.cumsum(a)) # [ 2 5 9 14 20 27 35 44 54 65 77 90]
#### 累差函数:计算每一行后一项与前一项的差,将差表示出来。
print(np.diff(a)) # [[1 1 1] [1 1 1] [1 1 1]]
#### 将矩阵中非零元素的行和列的值单独构成两个矩阵。
print(np.nonzero(a)) # (array([0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]), array([0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]))
# 排序:每一行单独排序,从小到大
a = np.arange(14, 2, -1).reshape((3, 4))
print(np.sort(a))
'''
[[11 12 13 14]
[ 7 8 9 10]
[ 3 4 5 6]]
'''
#### 转置
print(a.T)
'''
[[14 10 6]
[13 9 5]
[12 8 4]
[11 7 3]]
'''
#### 切分替换:将数组中大于最大值的数字用最大值代替,小于最小值的数字用最小值代替
print(np.clip(a, 5, 9))
'''
[[9 9 9 9]
[9 9 8 7]
[6 5 5 5]]
'''
4 numpy索引
import numpy as np
#### 一维矩阵索引
a = np.arange(3, 14)
print("一维数组下的第三个索引:", a[3]) # 一维数组下的第三个索引: 6
#### 二维矩阵索引
a = np.arange(3, 15).reshape((3, 4))
print(a)
'''
[[ 3 4 5 6]
[ 7 8 9 10]
[11 12 13 14]]
'''
print("二维数组下的第三个索引:", a[2]) # 这里输出的是第二行:[11 12 13 14]
#### 输出二维地址位置
print(a[1][1]) # 8
print(a[1, 1]) # 8
#### 利用 list 切片操作
print(a[1, 1:3]) # 将第2行的第2-4(但不包含第4列)的数据切分出来:[8 9]
#### 逐列打印操作:先转置,再输出
for column in a.T:
print(column)
'''
[ 3 7 11]
[ 4 8 12]
[ 5 9 13]
[ 6 10 14]
'''
#### 迭代输出,两种形式。
print(a.flatten()) # 将矩阵展开成 1 行的数列:[3 4 5 6 7 8 9 10 11 12 13 14]
#### # flat是一个定义好的迭代器,将每一个数据都迭代一遍输出。
for item in a.flat:
print(item) # 按照数一个一个输出 + 一个回车
'''
3
4
5
6
7
8
9
10
11
12
13
14
'''
5 numpy 合并
import numpy as np
a = np.array([1, 1, 1, 1])
b = np.array([2, 2, 2, 2])
#### vstack的数据合并
c = np.vstack((a, b))
print("a 的形状,b 的形状:", a.shape, c.shape) # a 的形状,b 的形状: (4,) (2, 4)
print(np.vstack((a, b))) # 纵合并
'''
[[1 1 1 1]
[2 2 2 2]]
'''
d = np.hstack((a, b)) # 横合并
print(d) # [1 1 1 1 2 2 2 2]
print(a.shape, d.shape) # (4,) (8,)
#### 一维数组不能通过转置变为二维列向量,转置之后仍然是一个一维数组。
a = np.array([1, 1, 1, 1])
print(a.T) # [1 1 1 1]
#### 1 * n 这种是不能利用 a.T 转置的,需要利用下面这种手法
a = a.reshape(-1, 1)
print("a 与 a 的形状:\n", a , a.shape)
'''
a 与 a 的形状:
[[1]
[1]
[1]
[1]] (4, 1)
'''
6 numpy 分割
import numpy as np
a = np.arange(12).reshape((3, 4))
print(a)
'''
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
'''
#### 等量分割
print("0 轴分割为 3 组:\n", np.split(a, 3, axis=0)) # 将3行分成一组
print("3轴纵向分割:\n", np.vsplit(a, 3)) # vertical split
'''
0 轴分割:
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
'''
print("1 轴分割为 2 组:\n", np.split(a, 2, axis=1)) # 将两列分成一组,且必须得是能分的,否则会报错。
print(np.hsplit(a, 2)) # horizon split
'''
1 轴分割:
[array([[0, 1] [4, 5] [8, 9]]), array([[2, 3] [6, 7] [10, 11]])]
'''
#### 不等量分割,优先满足第一个
print("1 轴分割为 3 组:\n", np.array_split(a, 3, axis=1))
'''
1 轴分割为 3 组:
[array([[0, 1], [4, 5], [8, 9]]), array([[2], [6], [10]]), array([[3], [7], [11]])]
'''
7 numpy 复制
import numpy as np
#### “ = ”符号就相当于对地址修改,一改全改。
a = np.arange(4)
print("修改前", a) # 修改前 [0 1 2 3]
d = a
d[0] = 11
print("修改后", a) # 修改后 [11 1 2 3]
# 利用copy得到的数据将不会有关联性。
a = np.arange(4)
print("修改前", a) # 修改前 [0 1 2 3]
d = a.copy()
d[0] = 22
print("修改后", a) # 修改后 [0 1 2 3]