好几天不写了,趁学完了numpy和matplotlib,纪念一下,此篇文章以代码为主,不会过多记录理论,如确实有需要,后续再找时间补上。
此篇文章分为两篇先从numpy部分入手,先谈numpy最基本的东西,然后用实例,结合matplotlib进行可视化。
一、Numpy
numpy是用于处理数值型数据的科学计算的标准库,多用于大型或多维数组上的计算。
(1)numpy数组的创建,直接上代码。
#先导入所需要的库
import numpy as np
#使用numpy创建数组
a = np.array(range(1, 10))#np.array里边可以传一个列表,或者直接用np.arange()
b = np.arange(1, 10)
print(a, "\n", b)#从输出结果可以看出,两个写法是一致的
print(a.dtype)#查看数据类型
#事实上,在创建数组的时候,也是可以指定数据类型的,如
c = np.array(range(1, 10),dtype= "int64")
print(c.dtype)#可以看到数据类型不是int32了,而是int64了
d = a.astype("float32")
print(d)#调整数据类型
#控制小数位数,如果是整数,如3.0,小数位数此处则不会显示
e = np.random.random(10)
print(np.round(e, 2))#设置结果保留两位小数
print(e.shape)#查看数组形状,结果显示为10行
np.random.seed(1)
f = np.random.random(size = (5, 2))#创建一个5*2的矩阵
print(f)
g = f.reshape(f.shape[0] * f.shape[1],)#修改矩阵形状,改为一维的
h = f.flatten()
print(g, h)#这两个结果是一样的
输出结果如下
[1 2 3 4 5 6 7 8 9]
[1 2 3 4 5 6 7 8 9]
int32
int64
[1. 2. 3. 4. 5. 6. 7. 8. 9.]
[0.65 0.82 0.87 0.68 0.57 0.54 0.55 0.53 0.01 0.77]
(10,)
[[4.17022005e-01 7.20324493e-01]
[1.14374817e-04 3.02332573e-01]
[1.46755891e-01 9.23385948e-02]
[1.86260211e-01 3.45560727e-01]
[3.96767474e-01 5.38816734e-01]]
[0.5881308 0.89771373 0.89153073 0.81583748 0.03588959 0.69175758
0.37868094 0.51851095 0.65795147 0.19385022]
[0.5881308 0.89771373 0.89153073 0.81583748 0.03588959 0.69175758
0.37868094 0.51851095 0.65795147 0.19385022]
(2)数组的计算与广播机制
第一种,是数组与数字运算(包括+, - ,* ,/),此时,把数组中每一个元素都和这个数做运算。
第二种,数组之间的运算,对应位置元素做运算即可(注意,这一部分的乘除和矩阵中的乘除是有区别的,当然,python也可以做矩阵乘除,但用的函数和这里是不一样的)。如果维度此时不一样,怎么办呢?这就不得不提广播机制了
广播原则是这样的: 如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符,或者其中一方长度为1,则认为它们是广播兼容的。广播会在轴缺失和(或)长度为1的维度上进行。
上面提到了一个新的概念,就是轴
轴简单来说,就是方向,以右手拇指指向屏幕内部,顺时针经过为轴的顺序。
在二维数组中,有两个轴,分为是横轴和纵轴,我们把右手拇指指向屏幕内,四根手指并拢顺时针转,则先过横轴,再过纵轴,那么,定义axis = 0为横轴,axis = 1为纵轴,如果是三维数组,则把拇指方向为0轴,axis = 1为横轴,axis = 2为纵轴。
在excel 表上看,那么,0跨列,1跨行
(3)numpy的其他小知识
numpy中还有一些其他的小功能,包括索引切片、读取数据,拼接、统计函数等等,在此直接在pycharm中进行,直接上代码及结果了
#(1)数组拼接
"""数组拼接有两种,一种是加行数(即在axis = 1的方向上加),使用np.vstack();
另外一种是加列数(即在axis = 0的方向上加),使用np.vstack()"""
#先准备两个数组
A = np.array(range(1,11)).reshape(2, 5)
print(A)
结果:
B = np.copy(A) + 10
print(B)
C = np.vstack((A, B))#注意是两个括号,因为vstack只允许传入一个参数
print(C)
D = np.hstack((A, B))
print(D)
E = np.hsplit(D, 5)#分割谁,分成几部分
print(E)
结果如下:
A
[[ 1 2 3 4 5]
[ 6 7 8 9 10]]
B
[[11 12 13 14 15]
[16 17 18 19 20]]
C
[[ 1 2 3 4 5]
[ 6 7 8 9 10]
[11 12 13 14 15]
[16 17 18 19 20]]
D
[[ 1 2 3 4 5 11 12 13 14 15]
[ 6 7 8 9 10 16 17 18 19 20]]
E
[array([[1, 2],
[6, 7]]), array([[3, 4],
[8, 9]]), array([[ 5, 11],
[10, 16]]), array([[12, 13],
[17, 18]]), array([[14, 15],
[19, 20]])]
以C为例,进行其他内容
#(2) 转置,索引,切片,修改数值,行列互换
#转置的三种方式
print(C.T)
print(C.swapaxes(1, 0))#传入交换的轴
print(np.transpose(C))
#索引和切片
#取一行
print(C[0, :])#取第一行
#取连续多行
print(C[2:, :])#取3,4行
#取不连续的多行
print(C[[0, 3], :])#取1, 4行
#取一列
print(C[:, 2])#取第三列
#取连续多列
print(C[:, 2:])#取3, 4, 5列
#取不连续的多列
print(C[:, [2, 4]])#取3, 5列
#既取行也取列(连续)
print(C[1:3, 2:4])#取2, 3行,同时满足在3, 4列,注意取左不取右,冒号右边那个是取不到的
#既取行也取列(不连续)
print(C[[2, 3], [1, 2]])#把数字12, 18取出来
#改值,把20改成21
C[3, 4] = 21
#交换最后两列
C[:, [-2, -1]] = C[:, [-1, -2]]
回到最初的C,除了上面取出一个要修改的值,然后重新赋值的方法,也可以使用下面的方法,下面的方法是根据布尔逻辑来的,也就是说,布尔值是可以直接参与运算的
C[C < 10] = 0#把小于10的换成0
print(C)
print(np.where(C < 10, 10, 20))#把小于10的换成10,大于10的换成20
print(C.clip(10, 15))#把汪于10的换成10,大于15的换成15
(4)函数
先说一下nan和inf。
inf表示无穷,有正无穷和负无穷之分。
nan指不是一个数字,通常由下面两种引起:①做了不合适的运算 ②浮点型数据有缺失值
nan有以下特性:
①两个nan是不相等的,即np.nan != np.nan
利用这个特性,可以判断nan的个数。如果没有nan,那么数组中各个值都相等,即数组A = A,但如果其中有nan,则A != A。判断是否是nan可以用np.isnan(),判断有几个nan,可以用np.count_nonzero(A!=A)
②nan与任何值计算均为nan
统计计算:
np.sum/C.sum
np.mean/C.mean
np.median
np.max/C.max
np.min/C.min
np.argmax
np.argmin
np.ptp
np.std
C = C.astype("float64")#转化为浮点型
C[1, 3] =np.nan
print(C)
print(np.count_nonzero(C!=C))
print(np.isnan(C))
print(np.sum(C, axis=1))
print(C.sum(axis = 1))