Numpy学习笔记
numpy简介
NumPy 是一个 Python 的第三方库,代表 “Numeric Python”,主要用于数学/科学计算。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。我们常用Numpy对数据进行处理,Numpy可以进行线性代数有关的操作。 NumPy 拥有线性代数和随机数生成的内置函数。
此外,NumPy 通常与 SciPy(Scientific Python)和 Matplotlib(绘图库)一起使用。 这种组合广泛用于替代 MatLab。
numpy属性
我们通过numpy中的array方法来生成一个矩阵。
而生成的矩阵具有一些属性,这里介绍结果常见属性:
ndim:该矩阵的维度;
shape:该矩阵的形状(几行几列);
size:元素个数。
import numpy as np
array = np.array([[1,2,3],[2,3,4]])
print(array)
# 维度
print('number of dimenson:', array.ndim)
# 形状
print('shape:', array.shape)
# 元素个数
print('size:', array.size)
输出结果:
[[1 2 3]
[2 3 4]]
number of dimenson: 2
shape: (2, 3)
size: 6
使用numpy创建数组
我们用numpy中的array方法来生成一个矩阵;
我们可以设置array中的参数dtype来指定该矩阵存储的数据类型;
# 指定数据类型
a = np.array([1, 2, 3], dtype=np.float)
print(a.dtype)
print(a)
float64
[1. 2. 3.]
我们可以使用numpy中的方法zeros来创建一个元素全是0的矩阵;
# 全0矩阵
a = np.zeros((3, 4), dtype=np.int)
print(a)
[[0 0 0 0]
[0 0 0 0]
[0 0 0 0]]
同样的,我们可以使用numpy中的方法ones来创建一个元素全是1的矩阵;
# 全1矩阵
a = np.ones((3, 4))
print(a)
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
我们可以用empty方法来生成一个未初始化的矩阵;
# 未初始化的矩阵
a = np.empty((3, 4))
print(a)
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
我们可以用arange方法来指定元素的范围及步长;
# 指定元素范围,[10, 20) 步长为2
a = np.arange(10, 20, 2)
print(a)
[10 12 14 16 18]
我们可以用reshape方法来重塑一个矩阵的形状;
# 指定矩阵形状
a = np.arange(10).reshape((5, 2))
print(a)
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
我们可以用linspace方法来生成等差数列,例如np.linspace(1, 10, 6)就是把1-10的数分成6份。
# 等差数列,[1,10]分成3份
a = np.linspace(1, 10, 6).reshape((2, 3))
print(a)
[[ 1. 2.8 4.6]
[ 6.4 8.2 10. ]]
numpy中对矩阵的基本运算
加减乘除次方
我们在numpy中可以对矩阵进行加减乘除和次方的运算,但是需要注意,用运算符进行运算时分别对矩阵中的每个数进行运算,比如说用 * 进行乘法运算,进行的是每个元素的乘法,而不是矩阵乘法,矩阵乘法在后面会讲到。
# 数组的加减乘除
a = np.array([10, 20, 30, 40])
b = np.array([1, 2, 3, 4])
print('a:', a)
print('b:', b)
c = a + b
print('a+b:', c)
c = a - b
print('a-b:', c)
c = a * b
print('a*b:', c)
c = a / b
print('a/b:', c)
c = a**2
print('a^3:', c)
a: [10 20 30 40]
b: [1 2 3 4]
a+b: [11 22 33 44]
a-b: [ 9 18 27 36]
a*b: [ 10 40 90 160]
a/b: [10. 10. 10. 10.]
a^3: [ 100 400 900 1600]
三角函数
numpy中有各种各样的三角函数操作。
# 三角函数
a = np.array([30, 45, 60, 90]) # 默认弧度制
pi = np.arcsin(1)*2
print(np.pi)
a = np.multiply(a, pi/180)
print('a:', a)
c = np.sin(a)
print(c)
c = np.cos(a)
print(c)
c = np.tan(a)
print(c)
3.141592653589793
a: [0.52359878 0.78539816 1.04719755 1.57079633]
[0.5 0.70710678 0.8660254 1. ]
[8.66025404e-01 7.07106781e-01 5.00000000e-01 6.12323400e-17]
[5.77350269e-01 1.00000000e+00 1.73205081e+00 1.63312394e+16]
生成随机矩阵
我们可以用random方法来生成随机矩阵;
用min函数来找出矩阵中的最小值;
用max函数来找出矩阵中的最大值;
用sum函数来计算矩阵中所有元素之和。
我们可以用axis来指定计算的是行还是列,0代表行,1代表列。
我们可以在上述的几个函数中指定axis,来返回对行或者列的计算。
# 随机生成矩阵
a = np.random.random((2, 4))
print(a)
print('min:', np.min(a))
print('max:', np.max(a))
print('sum:', np.sum(a))
# 1: 行 0: 列
print('min in each col:', np.min(a, axis=0))
print('min in each row:', np.min(a, axis=1))
[[0.33028884 0.20715399 0.67513249 0.7976253 ]
[0.09172116 0.65765596 0.04538128 0.36034413]]
min: 0.045381281632210335
max: 0.7976253001665536
sum: 3.165303150763041
min in each col: [0.09172116 0.20715399 0.04538128 0.36034413]
min in each row: [0.20715399 0.04538128]
数值运算
我们可以使用argmin和argmax函数来找出矩阵中的最小和最大值。
# 数值运算
a = np.arange(1, 13).reshape(3, 4)
print(a)
# 最小值索引
print(np.argmin(a))
# 最大值索引
print(np.argmax(a))
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
0
11
平均值
我可以用mean函数或者average函数来计算矩阵所有元素的平均值。
# 平均值
print(np.average(a))
print(np.mean(a))
print(a.mean())
6.5
6.5
6.5
中位数
我们可以用medium函数来计算矩阵所有元素的中位数。
# 中位数
print(np.median(a))
6.5
前缀和
我们用cumsum函数来计算矩阵的前缀和,即每个位置都是前面所有数的和。
# 前缀和
print(np.cumsum(a))
[ 1 3 6 10 15 21 28 36 45 55 66 78]
一阶差
我们用diff函数来计算矩阵中每个元素的一阶差,即该元素与前一个元素的差。
# 一阶差
print(np.diff(a))
[[1 1 1]
[1 1 1]
[1 1 1]]
非零的坐标
我们用nonzero函数来找出所有非零元素的行和列坐标。
# 非零的坐标
print(np.nonzero(a))
(array([0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2], dtype=int64), array([0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], dtype=int64))
逐行排序
我们用sort函数来对矩阵中的每一行进行逐行排序。
# 逐行排序
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]]
clip
我们用clip函数进行筛选操作,例如clip(a, 5, 10)会把大于10的数变成10,把小于5的数变成5.
# clip
print(a)
print(np.clip(a, 5, 10))
[[14 13 12 11]
[10 9 8 7]
[ 6 5 4 3]]
[[10 10 10 10]
[10 9 8 7]
[ 6 5 5 5]]
矩阵运算
矩阵乘法
我们刚才说了,运算符 * 只能计算对应元素的乘法,不能进行矩阵乘法。矩阵乘法需要用dot函数来完成。
# 矩阵相乘
a = np.array([[1,0], [1,2]])
b = np.arange(4).reshape(2,2)
print(a)
print(b)
c = np.dot(a, b)
# c = a.dot(b)
print(c)
[[1 0]
[1 2]]
[[0 1]
[2 3]]
[[0 1]
[4 7]]
矩阵转置
我们还可以通过numpy中的内置函数对矩阵进行转置。该函数为transpose。
# 矩阵转置
print(a)
print(np.transpose(a))
print(a.T)
[[1 0]
[1 2]]
[[1 1]
[0 2]]
[[1 1]
[0 2]]
索引
索引行
a = np.arange(1, 13).reshape(3, 4)
print(a)
# 第1行
print(a[1])
print(a[1, :])
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[5 6 7 8]
[5 6 7 8]
索引列
# 第1列
print(a[:,1])
[ 2 6 10]
索引元素
# 第1行的[1,3)
print(a[1, 1:3])
[6 7]
# 第(2,3)
print(a[2][3])
print(a[2, 3])
12
12
迭代行
# 迭代行
for row in a:
print(row)
[1 2 3 4]
[5 6 7 8]
[ 9 10 11 12]
迭代列
我们无法直接迭代列,所以需要将原矩阵转置,然后迭代转置后的矩阵。
# 迭代列
for row in a.T:
print(row)
[1 5 9]
[ 2 6 10]
[ 3 7 11]
[ 4 8 12]
迭代每一个元素
我们可以用flat函数来讲矩阵转为列表,再逐一遍历。
# 迭代每一个元素
print(a.flatten())
for item in a.flat:
print(item)
[ 1 2 3 4 5 6 7 8 9 10 11 12]
1
2
3
4
5
6
7
8
9
10
11
12
array合并
垂直和水平合并
我们用vstack函数和hstack函数分别进行垂直和水平合并。
A = np.array([1, 1, 1])
B = np.array([2, 2, 2])
# 垂直合并
C = np.vstack((A, B))
print(C)
# 水平合并
D = np.hstack((A, B))
print(D)
[[1 1 1]
[2 2 2]]
[1 1 1 2 2 2]
行列向量转换
我们可以用newaxis参数来增加维度,从而达到行列转换的效果。
# 数组转为行向量
print(A)
A = A[np.newaxis, :]
print(A)
[1 1 1]
[[1 1 1]]
# 数组转为列向量
print(B)
B = B[:, np.newaxis]
print(B)
[2 2 2]
[[2]
[2]
[2]]
concatenate合并
我们可以使用concatenate来进行合并,使用时只需要设置axis参数指定合并行还是列即可。
# concatenate合并
A = np.array([1, 1, 1])[:, np.newaxis]
B = np.array([2, 2, 2])[:, np.newaxis]
print(A)
print(B)
# 垂直合并
C = np.concatenate((A,B,B,A), axis=0)
# 水平合并
D = np.concatenate((A,B,B,A), axis=1)
print(C)
print(D)
[[1]
[1]
[1]]
[[2]
[2]
[2]]
[[1]
[1]
[1]
[2]
[2]
[2]
[2]
[2]
[2]
[1]
[1]
[1]]
[[1 2 2 1]
[1 2 2 1]
[1 2 2 1]]
array分割
等量分割
我们使用split函数进行等量分割,使用时指定参数axis。我们也可以使用vsplit函数和hsplit函数来进行上下和左右的分割。
# 等量分割
A = np.arange(12).reshape((3, 4))
print(A)
# 上下分割成3份
print(np.split(A, 3, axis=0))
print(np.vsplit(A, 3))
# 左右分割2份
print(np.split(A, 2, axis=1))
print(np.hsplit(A, 2))
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
不等量分割
当分割数和行或列数不能整除时,我们就需要使用不等量分割。
使用array_split函数进行不等量分割。
# 不等量分割
print(A)
t = np.array_split(A, 3, axis=1)
print(np.array_split(A, 3, axis=1))
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2],
[ 6],
[10]]), array([[ 3],
[ 7],
[11]])]
拷贝
拷贝分为两种,浅拷贝和深拷贝。
浅拷贝
直接赋值,当改变原矩阵时,赋值后的也会一同随着改变。
# 默认浅拷贝
a = np.arange(4)
b = a
a[1] = 5
print(a)
print(b)
[0 5 2 3]
[0 5 2 3]
深拷贝
我们使用copy函数来拷贝,拷贝后的矩阵不会随着原矩阵的改变而改变。
# 深拷贝
a = np.arange(4)
b = a.copy()
a[1] = 5
print(a)
print(b)
[0 5 2 3]
[0 1 2 3]