Python中Numpy的使用
Python的 Numpy 模块的基本用法
NumPy(Numerical Python)是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示矩阵(matrix)),支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。以下将介绍Numpy的一些基本应用
一.数组元素的基本类型
在进行数组的创建和操作前需要了解数组元素的数据类型,以下为numpy中的基本数据类型。
二.使用array创建一维数组
list = [1,2,3,4,5,6]
print(type(list)) # list对象
a = np.array(list)
print(a)
print(type(a)) # ndarray对象
# 打印数组中的元素类型
print(a.dtype) # int32 整数类型
print(a.shape) # 打印数组各个纬度的长度 结果是一个元组
代码运行结果:
<class ‘list’>
[1 2 3 4 5 6]
<class ‘numpy.ndarray’>
int32
(6,)
上述代码可以让我们清晰的明白numpy的array可以将list对象转化为ndarray数组对象,可以看到列表当中的每一个元素都由逗号隔开,而数组则没有。
三、使用zero/ones/empty 创建数组
# 创建一维长度为8,元素为0的数组
b = np.zeros(8)
print(b)
print(b.dtype) # 打印数组中元素的数据类型
print(b.shape) # 打印数组的形状
# 创建一维长度为2,二维长度为3,元素全部为零的数组
c = np.ones((2,3))
print(c)
print(c.dtype)
print(c.shape)
# 创建一维长度为2,二维长度为3,未初始化的二维数组
d = np.empty((2,3))
print(d)
print(d.dtype)
print(d.shape)
输出结果如下:
[0. 0. 0. 0. 0. 0. 0. 0.]
float64
(8,)
[[1. 1. 1.]
[1. 1. 1.]]
float64
(2, 3)
[[1. 1. 1.]
[1. 1. 1.]]
float64
(2, 3)
四、使用arange生成连续元素
e = np.arange(8) # [0,8) 右侧依旧是开区间
print(e)
f = np.arange(0,8,7)
print(g)
输出结果:
[0 1 2 3 4 5 6 7]
[0 7]
五、ndarry数组的转置和兑换
# 创建0-8组成的一维数组
g = np.arange(9)
# 将数组k升为二维的,每一个维度的长度为3
h = g.reshape((3,3))
print(g)
print(h)
# 转置数组(矩阵) --> m[x][y] == m[y][x]
print(h.T)
# 两个矩阵(二维数组)乘法
print(np.dot(h,h.T))
# 高维数组的轴对象
# 创建一个0-7元素组成的数组,数组的维度为3,每一维度的长度都为2
i = np.arange(8).reshape((2,2,2))
print(i)
# 获取到其中的6
print(i[1][1][0])
[0 1 2 3 4 5 6 7 8]
[[0 1 2]
[3 4 5]
[6 7 8]]
[[0 3 6]
[1 4 7]
[2 5 8]]
[[ 5 14 23]
[ 14 50 86]
[ 23 86 149]]
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
6
[[[0 1]
[4 5]]
[[2 3]
[6 7]]]
4
[[[0 1]
[4 5]]
[[2 3]
[6 7]]]
[[0 1 2]
[3 4 5]
[6 7 8]]
[[0 3 6]
[1 4 7]
[2 5 8]]
6、ndarry的一阶通用函数
函数 | 功能 |
---|---|
abs\fabs | 计算整数、浮点数的绝对值,对于非负数值,可以使用更块的fabs |
sqrt | 计算各元素的平方根 |
square | 计算各元素的平方 |
exp | 计算各元素的指数(e的x次方) |
log、log10、log2、log1p | 分别为自然对数(底数为e)、底数为10的log、底数为2的log、log(1+x) |
sign | 计算各元素的正负号:1(正数)、0(零)、-1(负数) |
ceil | 计算各元素的ceiling值,即大于等于该值的最小整数 |
floor | 计算各元素的floor值,即小于等于该值的最大整数 |
rint | 将各元素值四舍五入到最接近的整数,保留dtype |
modf | 将数组的小数和整数部分以两个独立数组形式返回 |
isnan | 返回一个表示“哪些值是NaN(这不是一个数字)”的布尔型数组 |
isfinite isinf | 分别返回一个表示“哪些元素是有穷的(非inf,非NaN)”或“哪些元素是无穷的”的布尔型数组 |
cos、cosh、sin、sinh、tan、tanh | 普通型和双曲型三角函数 |
arccos、arccosh、arcsin、arcsinh、arctan、arctanh | |
logical_not | 计算各元素not x 的真值。相当于-arr |
# 一元ufunc示例
m = np.arange(6)
print(m)
print(np.square(m))
n = np.array([-1.5,1.6,-1.7,1.8])
# modf 小数部分和整数部分分开显示
o,p = np.modf(n)
print(o,p)
# 向上最接近的整数
print(np.ceil(n))
# 向下最接近的整数
print(np.floor(n))
# 四舍五入后最接近的数
print(np.rint(n))
运行结果:
[0 1 2 3 4 5]
[ 0 1 4 9 16 25]
[-0.5 0.6 -0.7 0.8] [-1. 1. -1. 1.]
[-1. 2. -1. 2.]
[-2. 1. -2. 1.]
[-2. 2. -2. 2.]
七、ndarray的二阶通用函数
常用的二阶通用函数如下:
函数 | 功能 |
---|---|
add | 对应元素相加 |
subtract | 从第一个数组中减去第二个数组中的元素 |
multiply | 数组元素相乘 |
divide、floor_divide | 除法,或向下圆整除法(丢弃余数) |
power | 对第一个数组中的元素A,根据第二个数组中的相应元素B,计算A的B次方 |
maximum、fmax | 元素级的最大值计算。fmax将忽略NaN |
minimum、fmin | 元素级的最小值计算。fmin将忽略NaN |
mod | 元素级的求模计算(除法的余数) |
copysign | 将第二个数组中的值的符号复制给第一个数组中的值 |
greater、greater_equal、equal、notequeal | 执行元素级的比较运算,最终产生布尔型数组。相当于中缀运算符>、>=、<、<=、==、!= |
logical_and、logical_or、logical_xor | 执行元素级的真值逻辑运算。相当于中缀运算符&、 |
# 示例代码
q = np.array([[2,5],[9,13]])
r = np.array([[3,4],[10,12]])
print(np.maximum(q,r))
print(np.minimum(q,r))
# 对应元素相加加
print(np.add(q,r))
# 对应元素相减
print(np.subtract(q,r))
# 对应元素相乘
print(np.multiply(q,r))
# 除
# 结果留余数
print(np.divide(q,r))
# 结果小数部分直接舍去
print(np.floor_divide(q,r))
# 次方运算
print(np.power(q,4))
运算结果:
[[ 3 5]
[10 13]]
[[ 2 4]
[ 9 12]]
[[ 5 9]
[19 25]]
[[-1 1]
[-1 1]]
[[ 6 20]
[ 90 156]]
[[0.66666667 1.25 ]
[0.9 1.08333333]]
[[0 1]
[0 1]]
[[ 16 625]
[ 6561 28561]]
八、 numpy中where函数的用法
- np.where(condition,x,y) 满足条件就输出x,不满足就输出y
- np.where(condition) 输出满足条件的元素的坐标
# 首先介绍第一种使用方法:np.where(condition,x,y)
aa = np.arange(10)
print(np.where(aa,1,-1))# [-1 1 1 1 1 1 1 1 1 1] 0 为False所以输出的结果中第一个输出的结果为0
# aa数组中大于5的输出1,否则输出-1
print(np.where(aa>5,1,-1))
print(np.where([[True,False],[True,True]],[[1,2],[3,4]],[[9,8],[7,6]])) # 为True 就从[[1,2],[3,4]]中选,为False就从[[9,8],[7,6]]中选
# 第二种使用方法:np.where(condition) 没有x,y,情况下,会输出满足条件的元素坐标(有多少维,坐标也同样有多少维),最需要注意结果的数据类型为元组(tuple)
a = np.array([2,8,9,10,12,14])
# 返回满足条件的索引
print(np.where(a>5))
# 再通过索引拿到元素
print(a[np.where(a>5)])
print(np.where([[0,1],[1,0]])) # 因为是二维的,所以结果也自然是二维的了
运行结果:
[-1 1 1 1 1 1 1 1 1 1]
[-1 -1 -1 -1 -1 -1 1 1 1 1]
[[1 8]
[3 4]]
(array([1, 2, 3, 4, 5], dtype=int64),)
[ 8 9 10 12 14]
(array([0, 1], dtype=int64), array([1, 0], dtype=int64))
九、 常用的统计方法
# 注意,同一维度上的数组长度一致
x = np.array([[1,3],[2,5],[3,4]])
# 求所有元素的平均数(注意:零长度的数组mean为(n))
print(x.mean())
# 求每一行元素的平均数
print(x.mean(axis = 1))
# 求每一列元素的平均数
print(x.mean(axis = 0))
# 求和
print(x.sum())
# 求每一列元素之和
print(x.sum(axis =0))
# 求所有元素中的最大值
print(x.max())
# 求每一行的最大值
print(x.max(axis = 1))
# 求所有元素的累计和
print(x.cumsum()) # [ 1 4 6 11 14 18]
# 求所有元素的累计积
print(x.cumprod()) # [ 1 3 6 30 90 360]
# 布尔数组的常用统计方法
"""
sum: 统计数组/某一维度中True的个数
any: 统计数组/某一维度中是否存在一个/多个True
all: 统计数组/数组某一维度中是否都是True
"""
x = np.array([[False,True],[False,True]])
print(x.sum()) # 2
print(x.sum(axis = 0)) # [0 2]
print(x.any(axis = 0)) # [False True]
print(x.all(axis = 1)) # [False False]
运行结果:
3.0
[2. 3.5 3.5]
[2. 4.]
18
[ 6 12]
5
[3 5 4]
[ 1 4 6 11 14 18]
[ 1 3 6 30 90 360]
2
[0 2]
[False True]
[False False]
十、 数组去重以及集合运算
方法 | 功能 |
---|---|
unique(m) | 去重后有序排列 |
intersect1d(m,n) | 计算m和n中的公共元素 |
union1d(m,n) | 计算m和n中的并集 |
inld(m,n) | 判断m中的元素是否包含于n |
setdiff1d(m,n) | 计算集合的差集,即在m但不在n中的元素 |
setxorld(m,n) | 集合的对称差,即存在于一个数组中但不同时存在于两个数组中的元素 |
注意:以上所有方法返回内容的数据类型为一维数组
代码示例:
m = np.array([[1,6,5],[5,2,1],[6,3,2]])
# 元素去重
print(np.unique(m)) # [1 2 3 5 6]
n = np.array([1,6,2])
# 判断m的元素是否包含于n
print(np.in1d(m,n)) # # [ True True False False True True True False True]
# 计算差集
print(np.setdiff1d(m,n)) # [3 5]
# 获取共同元素
print(np.intersect1d(m,n)) # [1 2 6]
运行结果:
[1 2 3 5 6]
[ True True False False True True True False True]
[3 5]
[1 2 6]
十一、 numpy中的线性代数
方法 | 功能 |
---|---|
diag | 以一维数组的形式返回方阵对角线的元素 |
dot | 矩阵乘法 |
trace | 计算对角线元素的和 |
det | 计算矩阵行列式 |
eig | 计算方阵的本征值和本征向量 |
inv | 计算逆矩阵 |
pinv | 计算矩阵的Moore-Penrose 伪逆 |
qr | 计算QR分解 |
svd | 计算奇异值分解(SVD) |
solve | 解线性方程组Ax = b ,其中A为一个方阵 |
lstsq | 计算Ax = b 的最小二乘解 |
import numpy.linalg as npla
m = np.array([[1,3],[3,4]])
n = np.array([[2,4],[2,1]])
# 矩阵相乘
print(m.dot(n))
print(np.dot(m,n))
# 求逆矩阵
print(npla.inv(m))
# 求行列式
print(npla.det(m))
[[ 8 7]
[14 16]]
[[ 8 7]
[14 16]]
[[-0.8 0.6]
[ 0.6 -0.2]]
-5.000000000000001
十二、 numpy 中的随机数的生成
seed | 确定随机数生成器的种子 |
permutation | 返回一个序列的随机排列或返回一个随机排列的范围 |
shuffle | 对一个序列就地随机排列 |
rand | 产生均匀分布的样本值 |
randint | 指定范围内生成随机整数 |
randn | 产生正太分布(平均值为0,标准差为1)的样本值 |
binomial | 产生二项分布的样本值 |
normal | 产生正太(高斯)分布的样本值 |
beta | 产生beta分布的样本值 |
chisquare | 产生卡方分布的样本值 |
gamma | 产生gamma分布的样本值 |
uniform | 产生在[0,1]中均匀分布的样本值 |
import numpy.random as npr
# 随机选择20-80之间的数字
print(npr.randint(20,81))
# 随机从22,33,44,55,87,99,0中选取一个数字
print(npr.choice([22,33,44,55,87,99,0]))
# 随机100000次 0 和 1
x = npr.randint(0,2,size=100000)
# 随机数为1的次数
print((x>0).sum())
运算结果:
54
99
50075
十三、 ndarray数组的拆分和合并
# ndarray数组的拆分和合并
"""
concatenate 沿一条轴连接数组
vstack,row_stack 以面向行的方式对数组进行堆叠(沿轴0)
hstack 以面向行的方式对数组进行堆叠(沿轴1)
couum_stack 类似于hstack,但是会先将一维数组转换为二维列向量
dstack 以面向“深度”的方式对数组进行堆叠(沿轴2)
split 沿指定轴在指定的位置拆分数组
hspit,vsplit,dsplit split的便捷化函数,分别沿着轴0、轴1和轴2进行拆分
"""
m = np.array([[1,2,3],[4,5,6]])
n = np.array([[7,8,9],[10,11,12]])
# 垂直组合
print(np.concatenate([m,n],axis=0))
# 水平组合
print(np.concatenate([m,n],axis=1))
# 垂直:vstack
print(np.vstack((m,n)))
# 水平:hstack
print(np.hstack((m,n)))
# 按深度进行堆叠
print(np.dstack((m,n)))
# 按行分割 axis = 0 则是一维 一维度是的元素个数为2
print(np.split(m,2,axis=0))
# 按列分割 axis = 1 则表示二维 二维上的元素个数为3
print(np.split(m,3,axis=1))
运行结果:
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
[[ 1 2 3 7 8 9]
[ 4 5 6 10 11 12]]
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
[[ 1 2 3 7 8 9]
[ 4 5 6 10 11 12]]
[[[ 1 7]
[ 2 8]
[ 3 9]]
[[ 4 10]
[ 5 11]
[ 6 12]]]
[array([[1, 2, 3]]), array([[4, 5, 6]])]
[array([[1],
[4]]), array([[2],
[5]]), array([[3],
[6]])]
作者:lovers_better