1、numpy库介绍
1.1、Numpy库概述
- 主要用于对多维数组执行计算,是一个非常高效的用于处理数值运算的包
- 特点
- 1、numpy底层内置了并行运算功能,当系统有多个核心时,做某种计算时,numpy会自动做并行计算
- 2、Numpy底层使用C语言编写,内部解除了GIL(全局解释器锁),对数组的操作速度不受Python解释器的限制,效率远高于纯Python代码。
- 3、有一个强大的N维数组对象Array(一种类似列表的东西)
- 4、使用的线性代数、傅里叶变换和随机生成函数
1.2、numpy数组和Python列表性能对比
- 使用python列表创建随机数
#获取当前时间戳
t1 = time.time()
a = []
for x in range(1000000):
a.append(x**2)
t2 = time.time()
print(t2-t1)
- 查询结果
- 使用numpy创建随机数
t3 = time.time()
b = np.arange(1000000)**2
t4 = time.time()
print(t4-t3)
- 查询结果
1.3、数组和列表对比
- numpy中的数组使用跟Python中的列表非常类似,区别如下
- 1、一个列表中可以存储多种数据类型,而数组只能存储同种数据类型
- 2、数组可以是多维的,当数组中的所有数据类型都是数值型的时候,相当于线性代数中的矩阵,是可以进行相互间的运算的
2、数组的创建方式
- numpy经常和数组打交道,因此第一步是要学会创建数组。在numpy中的数组的数据类型叫做ndarray
2.1、使用np.array创建(列表)
b = np.array([1,2,3,4])
print(b)
print(type(b))
- 运行结果
2.2、使用np.arange创建 (等差序列)
arr2 = np.arange(0,10,2)
print(arr2)
print(type(arr2))
- 运行结果
2.3、使用np.random创建(随机数)
arr3 = np.random.random(10)
print(arr3)
print(type(arr3))
- 运行结果
2.4、使用函数创建(特殊数)
a1 = np.zeros((2,2))
a2 = np.ones((3,2))
a3 = np.full((2,2),8) #生成一个所有元素都是8的2行2列的数组
a4 = np.eye(3) #生成一个在斜方形上元素为1,其余元素为0的3*3的矩阵
print(a1)
print(a2)
print(a3)
print(a4)
- 运行结果
3、数组常用属性
3.1、数组数据类型
bool,int8,int16,int32,int64,uint8,uint16,uint32,uint64
object_,string_,unicode_
- 范例
c = np.array([1,2,3,4],dtype=np.float16)
print(c)
print(c.dtype)
- 运行结果
3.2、数据类型转换
- 类型转换:文件加载完毕后,为了减小内存空间,转换其数据类型
import numpy as np
a1 = np.array([1,2,3])
print(a1.dtype) # windows下默认为int32
a2 = a1.astype(np.int8) #astype不会修改数组本身,二十返回修改数据结果
print(a2)
- 查询结果
4、多维数组
4.1、多维数组的创建
shape:查看数组维度
ndim:查看数组维度
size:查看数组元素个数
itemsize:查看数组中每个元素所占大小,单位是字节
- 范例
a1 = np.array([1,2,3,4])
a2 = np.array([[1,2,3,4],[5,6,7,8]])
a3 = np.array([[[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4]]])
print(a1.shape)
print(a2.shape)
print(a3.shape)
- 查询结果
4.2、维度转换
reshape:维度转换,不会修改数组本身
resize:维度转换,会修改数组本身
flatten:维度转换成一维,返回原数组副本
ravel:维度转换为一维,返回原数组引用
- 范例一
a4 = a3.reshape((4,4))
print(a4)
print(a4.shape)
- 查询结果
- 范例二
a1 = np.random.randint(0,5,size=(3,2,2))
a2 = np.random.randint(0,5,size=(2,2))
print(a1.flatten())
print("========")
print(a1)
print("========")
print(a2.ravel())
print("========")
print(a2)
print("========")
print(a1+a2)
- 查询结果
- 开发常用 - 转换成一维数组
a5 = a3.reshape((16,))
print(a5)
print(a5.shape)
- 查询结果
4.3、axis轴理解
- 最外面的括号代表axis=0,依次往里的括号对应的axis的计数依次加1
- 操作方式:如果指定轴进行相关操作,那么会使用该轴下的每个直接子元素分别进行相关操作
- 范例
arr1 = np.arange(0,6).reshape(2,3)
arr2 = np.arange(6,12).reshape(2,3)
print(arr1+arr2)
- 查询结果
4.4、多维数组总结
1、数组一般达到三维就已经很复杂了,不太方便计算,所以我们一般都会把3维以上的数组转换成2维数组来计算
2、ndarray.ndim:查看数组维度
3、ndarray.shape:查看数组形状,shape是一个元组,里面有几个元素代表几维数组
4、ndarray.reshape:修改数组的形状,修改前后的元素总数必须一致
5、ndarray.size:看到数组总共元素个数
6、ndarray.itemsize:查看数组每个元素所占内存大小
5、数组的切片和索引
5.1、一维数组的切片和索引
包括:[起始位置:结束位置:步长]
- 范例
a6 = np.arange(10)
print(a6)
print(a6[1])
print(a6[0:4])
print(a6[0:6:2])
print(a6[::-1])
- 查询结果
5.2、多维数组的切片和索引
多维数组:
中括号一个值:代表行
中括号两个值:逗号分隔,都好前面是行,逗号后面是列,结果为一维数组
- 范例
a7 = np.random.randint(0,10,size=(4,6))
print(a7)
print("============")
print(a7[1])
print("============")
print(a7[0:2])
print("============")
print(a7[[0,2,3]])
print("============")
print(a7[0:2,0])
- 查询结果
5.3、布尔索引
布尔索引:<,>,<=,>=,==,!=,&,|
- 范例:将数组a7中所有小于5且大于3的数据全部提取出来
a8 = [(a7 < 5) & (a7>3)]
print(a8)
print("============")
print(a7[a8])
- 查询结果
- 注意事项
布尔索引:通过相同数组上的True还是False来进行提取
提取条件多个: & 代表且, | 代表或, 每个条件都要用圆括号括起来
6、数组值的替换
6.1、索引替换
- 范例
a7[a7 < 3] = 1
a7
- 查询结果
6.2、函数替换
np.where(条件,0,1)
- 范例
result = np.where(a7 > 5 ,0,1)
result
- 查询结果
7、数组广播机制
7.1、数组与常数的运算
- 范例
a1 = np.arange(10).reshape(2,5)
print(a1)
a2 = a1 + 10
print(a2)
- 查询结果
7.2、数组与数组的运算
(1)相同结构运算
直接相加
- 范例
a1 = np.arange(10).reshape(2,5)
print(a1)
print("=======")
a2 = a1 + 10
print(a2)
print("=======")
a3 = a1 + a2
print(a3)
print("=======")
- 查询结果
(2)不同结构运算
1、两数组其中一方长度为1,则广播兼容
2、两数组从末尾开始算起的维度的轴长度相符,则广播兼容
- 范例一
a1 = np.random.randint(0,5,size=(3,8,2))
a2 = np.random.randint(0,5,size=(8,1))
print(a1)
print("========")
print(a2)
print("========")
print(a1+a2)
- 查询结果
- 范例二
a1 = np.random.randint(0,5,size=(3,2,2))
a2 = np.random.randint(0,5,size=(2,2))
print(a1)
print("========")
print(a2)
print("========")
print(a1+a2)
- 查询结果
7.3、数组叠加
(1)垂直方向叠加
vstack:数组垂直方向叠加,
前提条件:数组列数必须相同
- 范例
a1 = np.random.randint(0,5,size=(2,2))
a2 = np.random.randint(0,5,size=(2,2))
a3 = np.vstack([a1,a2])
print(a3)
- 查询结果
(2)水平方向叠加
hstack:将数组按水平方向叠加
前提条件:数组的行必须相同才能叠加
- 范例
a1 = np.random.randint(0,5,size=(2,2))
a2 = np.random.randint(0,5,size=(2,2))
a3 = np.hstack([a1,a2])
print(a3)
- 查询结果
(3)手动指定
concatenate:将两个数组进行叠加,具体方向看参数axis
- 范例
a1 = np.random.randint(0,5,size=(2,2))
a2 = np.random.randint(0,5,size=(2,2))
a3 = np.concatenate([a1,a2],axis=None)
a4 = np.concatenate([a1,a2],axis=1)
a5 = np.concatenate([a1,a2],axis=0)
print(a3)
print(a4)
print(a5)
- 查询结果
7.4、数组切割
(1)水平切割
hsplit:水平切割
- 范例
a1 = np.random.randint(0,5,size=(2,2))
np.hsplit(a1,2)
- 查询结果
(2)垂直切割
vsplit:按照垂直方向进行分割
- 范例
a1 = np.random.randint(0,5,size=(2,2))
np.vsplit(a1,2)
- 查询结果
(3)指定方向
split:指定方向切割,参数axis0为行,1为列
- 范例
a1 = np.random.randint(0,5,size=(2,2))
a2 = np.split(a1,2,axis=0)
print(a2)
a3 = np.split(a1,2,axis=1)
print(a3)
- 查询结果
7.5、数组转置
转置:矩阵内积计算
- 范例
a1 = np.random.randint(0,5,size=(2,2))
print(a1)
print("=====")
print(a1.T)
print("=====")
print(a1.dot(a1.T))
- 查询结果
8、数组的深/浅拷贝
不拷贝:简单赋值不会拷贝
浅拷贝:变量拷贝,所指向内存空间相同
深拷贝:
- 范例
a = np.random.randint(0,5,size=(2,2))
b = a
print(b is a)
print("======")
c = a.view()
print(c is a)
c[[0],[0]] = 100
print(c)
print(a)
print("======")
d = a.copy()
d[[1],[1]] = 10
print(d)
print(a)
- 查询结果
9、文件操作
numpy文件格式:npy或者npz结尾
9.1、读取文件
np.savetxt:保存文件格式,顶部标记,分隔符
- 范例
a = np.random.randint(0,100,size=(4,4))
np.savetxt("a.csv",a,delimiter=",",header="a,b,c,d")
- 查询结果
9.2、文件保存
np.loadtxt:数据类型,分隔符,跳行
- 范例
data = np.loadtxt("b.csv",delimiter=",")
data
- 查询结果
9.3、读取非文本文件
np.load:读取非文本文件格式,可用于三维数组以上
- 范例
np.load("a.npy")
- 查询结果
9.4、保存非文本文件
np.save:保存非文本文件格式,可用于三维数组以上
- 范例
a = np.random.randint(0,100,size=(4,4,4))
np.save("a.npy",a)
- 查询结果
9.5、写入CSV文件
with open(文件名称,读,编码方式) as 对象名称:
reader = csv.reader(fp)
reader = csv.DictReader(fp)
- CSV文件
CSV文件特征
:1、纯文本,使用某个字符集,比如ASCII、Unicode
:2、由记录组成
:3、每条记录被分割符分割为字段(典型分隔符有逗号,分号,制表符)
:4、每条字段有同样的字段序列
- 范例 - 迭代器(列表形式)读取文件内容
import csv
with open('b.csv','r') as fp:
#reader是一个迭代器
reader = csv.reader(fp)
#next取出第一个指针指向的数据,之后下移
titles = next(reader)
print(titles)
print("=========")
for x in reader:
print(x)
print("========")
a = x[0]
b = x[1]
print(a+b+"结果")
- 查询结果
- 范例 - 迭代器(字典形式)读取文件内容
with open("b.csv",'r') as fp:
reader = csv.DictReader(fp)
for x in reader:
print(x)
- 查询结果
9.6、读取CSV文件
with open(文件名称,写入,编码格式):
writer = csv.writer(fp)
writer.writerow #写入一行
writer.writerows #写入多行
- 范例 - 一次性写入多行数据
headers = {"username","age","height"}
values = [('张三',18,200),('李四',19,180)]
with open('c.csv','w',encoding='utf-8') as fp:
writer = csv.writer(fp)
writer.writerow(headers)
writer.writerows(values)
- 查询结果
10、NAN和INF值处理
NAN:Not A Number,不是一个数字,属于浮点类型
INF:Infinity,代表无穷大,除数为0时出现,也是与浮点类型
- NAN的特点:
:1、NAN和NAN不相等,比如np.NAN 1= np.NAN这个条件是成立的
:2、NAN和任何值做运算,结果都是NAN
(1)删除缺失值
data[~np.isnan(data)] :删除空值,将数组转换为一维数组
np.delete(data,np.where(np.isnan(data))[0],axis=0) :删除为NAN的行
- 范例 - 删除空值,转换为一维
import numpy as np
# 1、删除所有NAN的值,因为删除了值后数组不知道怎么变化,所以会变成一维数组
data = np.random.randint(0,10,size = (3,5)).astype(np.float)
data[0:1] = np.nan
data = data[~np.isnan(data)]
print(data)
- 查询语句
- 范例 - 删除空值所在的行
import numpy as np
# 1、删除所有NAN的值,因为删除了值后数组不知道怎么变化,所以会变成一维数组
data = np.random.randint(0,10,size = (3,5)).astype(np.float)
#将0,1和1,2两个值设置为NAN
data[[0,1],[1,2]] = np.nan
#获取那些行有NAN
lines = np.where(np.isnan(data))[0]
#使用delete方法删除指定的行,axis = 0表示删除,lines表示删除的符号
data1 = np.delete(data,lines,axis=0)
print(data1)
- 查询语句
(2)用其他值进行替换
1、将空值替换为0
2、将空值替换为均值
- 范例
#CSV文件空缺值为空字符串,读取时限定字符串格式
scores = np.loadtxt("学习成绩.csv",delimiter = ',',encoding='utf-8',skiprows=1,dtype=np.str)
# 将空字符串转换为NAN
scores[scores == ""] = np.NAN
scores.astype(np.float)
# 将字符串全部转换为浮点类型
scores.astype(np.float)
- 查询结果
- 注意事项
读取CSV文本中的空值:
:1、先以字符串类型读取,
:2、空字符串转换为NAN
:3、将字符串转换为浮点类型
11、random模块
(1)随机数种子seed
- 用于指定随机数生成算法开始的整数值
相同seed值:每次生成的随机数都相同
不设置seed值:根据系统时间选择这个值
- 范例
np.random.seed(1)
print(np.random.rand()) #打印固定值
print(np.random.rand()) #打印其他值,因为随机数种子只对下一次随机数的产生有影响
- 查询结果
(2)随机数数组
- 范例
print(np.random.rand(2,3,4)) #生成两块3行4列的数组,值在0-1之间
- 查询结果
(3)随机数数组 - 标准正态分布
- 范例
print(np.random.randn(2,3)) #生成一个2行3列的数组,数组中的值都满足正态分布
- 查询结果
(4)随机数数组 - 指定范围
- 范例
print(np.random.randint(10,size=(3,6)))
- 查询结果
(5)随机采样
前提条件:必须是一维数组
- 范例
data = [1,2,3,4,5,6,7,8,9,10]
result1 = np.random.choice(data,3)
result2 = np.random.choice(data,size=(2,2))
print(result1)
print("========")
print(result2)
- 查询结果
12、通用函数
12.1、一元函数
函数 | 描述 |
np.abs | 绝对值 |
np.sqrt | 开根 |
np.square | 平方 |
np.exp | 计算指数e*x |
np.log,np.log10,np.log2,np.log1p | 求对数 |
np.sign | 标签化,1,0,-1 |
12.2、二元函数
函数名称 | 描述 |
np.add | 加法 |
np.substract | 减法 |
np.negative | 负数,每个值加个符号 |
np.multiply | 乘法 |
np.divide | 除法 |
np.floor_divide | 取整 |
np.mod | 取余 |
12.3、聚合函数
函数名称 | 描述 |
np.sum | 元素和 |
np.prod | 元素积 |
np.mean | 元素均值 |
np.std | 元素标准差 |
np.var | 元素方差 |
np.min | 元素最小值 |
np.max | 元素最大值 |
np.median | 元素中位数 |
np.argmax | 元素最大值索引 |
np.argmin | 元素最小值索引 |
12.4、布尔判断函数
函数名称 | 函数描述 |
np.any | 验证任意一个元素是否为真 |
np.all | 验证所有元素是否为真 |
- 范例
data = np.random.randint(10,size=(3,4))
print(np.any(data == 5))
print(np.all(data == 5))
- 查询结果
12.5、排序
函数名称 | 函数描述 |
np.sort | 指定轴进行排序,默认最后一个轴 |
np.argsort | 返回排序后的下标值 |
- 范例
data = np.random.randint(10,size=(3,4))
data1 = np.sort(data)
data2 = np.sort(data,axis=0)
data3 = np.argsort(data)
print(data1)
print("========")
print(data2)
print("========")
print(data3)
print("========")
- 查询结果
12.6、其他函数补充
函数名称 | 函数描述 |
np.apply_along_axis | 沿着某这轴执行函数 |
np.linespace | 指定区间内的值平均分成多少份 |
np.unique | 返回数组中的唯一值 |