Numpy
NumPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。
Numeric,即 NumPy 的前身,是由 Jim Hugunin 开发的。 也开发了另一个包 Numarray ,它拥有一些额外的功能。 2005年,Travis Oliphant 通过将 Numarray 的功能集成到 Numeric 包中来创建 NumPy 包。 这个开源项目有很多贡献者。
程序员在使用numpy时一般将numpy定义为np来进行使用。
import numpy as np
Numpy基础操作
创建一个array,用np.array会将数据转化为矩阵。
array = np.array([[1, 2, 3], [4, 5, 6]])
输出结果:array=[[1 2 3] [4 5 6]]
array可以查看他的维度,形状和大小。分别使用ndim,shape和size
print(f'number of dim:{array.ndim}')
print(f'shape:{array.shape}')
print(f'size:{array.size}')
输出结果为:number of dim:2 shape:(2, 3) size:6
在创建array时如果想要定义数据类型可以使用dype参数
array = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.int)
print(f'array的类型是:{array.dtype}')
输出:array的类型是:int32
生成全为一的矩阵使用.ones
要注意ones中接收元组类型变量时生成相对应大小的矩阵,如果接收int型变量n则生成(1, 3)的矩阵。
array = np.ones((3, 4)) # (3, 4)代表矩阵形状
print(f'ones:{array}')
输出结果为:
ones:[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
生成全0矩阵使用zeros,与生成全1矩阵用法完全相同:
array = np.zeros((3, 4), dtype=np.int) # (3, 4)代表矩阵形状
print(f'zeros:{array}')
输出:
zeros:[[0 0 0 0]
[0 0 0 0]
[0 0 0 0]]
生成有序数列 arange相当于python中的range
array = np.arange(10, 20)
print(f'arrange:{array}')
输出结果:arrange:[10 11 12 13 14 15 16 17 18 19]
完全随机生成array (0-1)
array = np.random.random((2, 4))
print(f'random={array}')
输出结果:
random=[[0.97255431 0.95371443 0.66254579 0.64624345]
[0.97191376 0.06827403 0.54682771 0.62211191]]
改变当前矩阵形状使用reshape函数
需要注意的是reshape接收的参数也是元组类型,矩阵形状中的数据数量一定要与之前矩阵的数据数量相同,如果不确定数据数量,可以只设置行或列,而另一部分用-1表示,这样系统会自动计算另一部分。
array = np.arange(15).reshape((3,5))
print(f'reshape:{array}')
输出结果:
reshape:[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
生成一个线段 :linspace
linspace(a, b, c),在[a, b],区间内生成c个数。
array = np.linspace(1, 10, 20).reshape((4, 5)) # 生成 1-10共20个数的一个数列
print(f'linspace:{array}')
输出结果:
linspace:[[ 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. ]]
Numpy运算
生成矩阵:
a = np.array([10, 20, 30, 40])
b = np.arange(4)
print(a, b)
基础运算
下方的运算均是两个矩阵相对应的点对点之间的运算。
# 加法运算
c = a + b
print(f'加法运算:c={c}')
# 减法运算
c = a - b
print(f'减法运算:c={c}')
# 乘法运算 两个矩阵对应元素分别相乘
c = b * a
print(f'乘法运算:c={c}')
# 三角函数运算
c = np.sin(a)
print(f'sin(a)={c}')
# 不等运算,得到True or False
print(f'b>3={b < 3}')
输出结果:
加法运算:c=[10 21 32 43]
减法运算:c=[10 19 28 37]
乘法运算:c=[ 0 20 60 120]
sin(a)=[-0.54402111 0.91294525 -0.98803162 0.74511316]
b>3=[ True True True False]
矩阵乘法运算:
矩阵乘法运算用多种写法,如下方代码所示:
a = np.array([[1, 1], [0, 1]])
b = np.arange(4).reshape((2, 2))
c = a * b
c_dot = np.dot(a, b) # 矩阵相乘
c_dot_2 = a.dot(b)
print(f'c={c}')
print(f'c_dot={c_dot}')
print(f'c_dot_2={c_dot_2}')
c = a*b是点对点的计算。dot才是矩阵乘法运算。
c=[[0 1]
[0 3]]
c_dot=[[2 4]
[2 3]]
c_dot_2=[[2 4]
[2 3]]
矩阵内部运算:
axis用来为超过一维的数组定义属性。二维数据拥有两个轴:第0轴沿着行的方向垂直向下,第1轴沿着列的方向水平延申。1表示横轴,方向从左到右;0表示纵轴,方向从上到下。当axis=1时,数组的变化是横向的,体现出列的增加或者减少。反之,当axis=0时,数组的变化是纵向的,体现出行的增加或减少。
# 矩阵内部求和
a = np.random.random((3, 4))
print(a)
print(f'sum={np.sum(a, axis=1)}') # axis=1在行运算,axis=0在列运算,不写axis则全局运算
# 矩阵内部找最大值
print(f'max={np.max(a, axis=1)}')
# 矩阵内部找最小值
print(f'min={np.min(a, axis=0)}')
输出结果:
[[0.53846511 0.0521948 0.23159535 0.4846488 ]
[0.87195444 0.67864654 0.25292788 0.86278436]
[0.00678497 0.60631157 0.82977758 0.61724833]]
sum=[1.30690405 2.66631322 2.06012245]
max=[0.53846511 0.87195444 0.82977758]
min=[0.00678497 0.0521948 0.23159535 0.4846488 ]
axis=1时,在一整行中找对应值,因为由三行,所以sum和max有三个值,axis=0时在一整列中找对应值,因为有四列,所有min有四个值。
矩阵索引
# 创建矩阵
A = np.arange(2, 14).reshape((3, 4))
print(f"A={A}")
# 对最小值的索引
print(f'最小值的索引={np.argmin(A)}')
# 对最大值的索引
print(f'最大值的索引={np.argmax(A)}')
输出结果:
最小值的索引=0
最大值的索引=11
求平均值和中位数
平均值有多种写法,如下方代码所示。
# 计算矩阵的平均值
print(f'平均值={np.mean(A)}')
print(f'平均值={A.mean()}')
print(f'平均值={np.average(A)}')
# 计算矩阵的中位数
print(f'中位数={np.median(A)}')
输出结果:
平均值=7.5
平均值=7.5
平均值=7.5
中位数=7.5
矩阵迭代操作
# 求累加
print(f'累加过程记录:{np.cumsum(A)}')
# 累差
print(f'累差={np.diff(A)}')
# 排序
A = np.arange(14, 2, -1).reshape((3, 4))
print(f'A={A}')
print(f'排序={np.sort(A)}')
输出结果:
累加过程记录:[ 2 5 9 14 20 27 35 44 54 65 77 90]
累差=[[1 1 1]
[1 1 1]
[1 1 1]]
A=[[14 13 12 11]
[10 9 8 7]
[ 6 5 4 3]]
排序=[[11 12 13 14]
[ 7 8 9 10]
[ 3 4 5 6]]
矩阵转置
# 矩阵的转置
A = np.arange(2, 14).reshape((3, 4))
print(f'A={A}')
print(f"转置后的A={A.T}")
print(f'转置后的A={np.transpose(A)}')
两种方式均可以对矩阵进行转置。
输出结果:
转置后的A=[[ 2 6 10]
[ 3 7 11]
[ 4 8 12]
[ 5 9 13]]
转置后的A=[[ 2 6 10]
[ 3 7 11]
[ 4 8 12]
[ 5 9 13]]
矩阵索引
矩阵索引和对列表的索引非常像。
# 索引
A = np.arange(12).reshape((3, 4))
print(f'A={A}')
print(f'A[2]={A[2]}')
print(f'A[2][2]={A[2][2]}')
print(f'A[2][2]={A[2, 2]}')
print(f'第二行的所有数:{A[2,:]}')
print(f'第一列的所有数:{A[:, 1]}')
输出结果:
A=[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
A[2]=[ 8 9 10 11]
A[2][2]=10
A[2][2]=10
第二行的所有数:[ 8 9 10 11]
第一列的所有数:[1 5 9]
矩阵合并
np.newaxis的功能:插入新维度
# array 合并
A = np.array([1, 1, 1])
B = np.array([2, 2, 2])
print(f'上下合并={np.vstack((A, B))}')
print(f'左右合并={np.hstack((A, B))}')
A = A[:, np.newaxis]
B = B[:, np.newaxis]
print(f'上下合并={np.vstack((A, B))}')
print(f'左右合并={np.hstack((A, B))}')
输出结果:
上下合并=[[1 1 1]
[2 2 2]]
左右合并=[1 1 1 2 2 2]
上下合并=[[1]
[1]
[1]
[2]
[2]
[2]]
左右合并=[[1 2]
[1 2]
[1 2]]