numpy创建数组
导包
import numpy as np
numpy中数组和python中列表相似。
区别:
1.列表可以存储多种数据类型 例:a=[1,‘a’],数组只能存储同种数据类型。
有字符串都转化为字符串,有浮点数都转化为浮点数
2.数组可以多维,多维数组的值也是数组,若多维数组数据的类型相同,可进行运算。
创建数组
- np.array()
a=np.array([1,2,3,4])
- np.arange(X,Y,sep)
产生一个X到Y的区间,sep是步长
a=np.arange(0,10)#0到9的区间 没有10
- np.random()
生成随机数的数组
a=np.random.random()#返回一个0-1的随机数
a=np.random.random(2,2)#生成2行2列的随机数的数组,每个数都是0-1
a=np.random.randint(0,9,size=(N,M))#创建一个N行M列的数组,值的范围通过前两个参数确定
- np的特殊函数生成特殊数组
a=np.zeros((3,3))#3行3列的元素全是0的数组
a=np.ones((4,4))#4行4列的元素全是1的数组
a=np.full((2,3),9)#2行3列的元素全是9的数组
a=np.eye(N)#N维单位矩阵数组
1. 数组数据类型
图片取自菜鸟教程
- 查看数据类型
a=np.array([1,2,3])
print(a)
print(a.dtype)
- 可指定数组的数据类型
a=np.array(['a','b'],dtype='string_')
print(a.dtype)
- 改变数据类型
a.astype(‘改变后的数据类型’)
#假设f为'S'类型
uf=f.astype("U")
print(f.dtype)#f的类型不会变,还是S
print(uf.dtype)#uf的类型为U
数据准备
a1=np.array([1,2,3])
a2=np.array([1,2,3],[4,5,6])
a3=np.array(
[
[1,2,3],
[4,5,6]
]
,[
[7,8,9],
[10,11,12]
])
- ndarray.ndim
查看数组的维数
print(a1.ndim)#1
print(a2.ndim)#2
print(a3.ndim)#3
- ndarray.shape
数组的每个维度的数
例如二维数组:查看是几行几列
print(a1.shape)#((3,)
print(a2.shape)#(2,3)
print(a3.shape)#(2,2,3)
a4=np.array([1,2,3],[4,5])
print(a4)#[list([1, 2, 3]) list([4, 5])]
print(a4.shape)#(2,)
- ndarray.reshape
重新修改数组维数 三维及以上的数组,一般转化为一维二维进行处理
#三维转化为二维
a5=a3.reshape((2,6))
print(a5)
print(a5.shape)#(2,6)
#三维转化为一维
a5=a3.reshape((1,12))
print(a5)#[[1 2 3 4 5 6 7 8 9 10 11 12]] 是二维数组
#正确转换方法
#1.
a5=a3.reshape((12,))
print(a5)#[1 2 3 4 5 6 7 8 9 10 11 12]
#2.扁平化方法函数flatten()
a5=a3.flatten()
多维数组及其部分操作
用arange创建多维数组:
a=np.arange(1,9).reshape(3,3)
- ndarray.size
获取数中的总元素个数
print(a2.size)#6 一共6个元素,所以打印6
- ndarray.itemsize
每个元素所占内存的大小,单位字节byte
(1个字节=8位)
可用于求一个数组所占总内存
item=a3.itemsize
#求一个数组所占总内存:总元素数*每个元素所占内存大小
print(item*a3.size)
数组索引、切片
1. 若是一维数组,和python列表一样。
a1=np.arange(10)
#索引
print(a1[2])
#用负数作为索引
print(a1[-1])
#切片
print(a1[4:6])#array([4,5])
#使用步长
pint(a1[::2])
2. 多维数组(以二维数组为例)
多维数组也是通过中括号进行索引切片,中括号中用逗号分隔行和列。
若二维数组只有一个值,这个值是行。若三维数组只有一个值,是块
数据准备
a2=np.random.randint(5,10,size=(4,6))
#连续行
a2[1:3]#获取2、3行
#不连续行
a2[[0,2,3]]#获取1,3,4行
#找元素
a2[2,1]#第三行第二列的数
对比以下两种方法的区别
#定点获取元素
a2[[1,2],[4,5]]#获取第二行第五列和第三行第六列的数
#[[第一个数行数,第二个数行数],[第一个数列数,第二个数列数]]
#获取某一片数据
a2[1:3,4:6]#获取2到三行、五到六列的那四个数据
a2[:,1]#获得第二列的数据,第一个“:”表示是连续的
a2[:,[1,3]]#获得第二、三列的数据,第一个“:”表示是连续的
':‘表示连续,’,'表示不连续和分隔行、列
不连续的,要用中括号[]括起来,用逗号分隔,连续的不需要用中括号[]括起来,用“:”分隔
3. 布尔索引
数据准备
a=np.arange(24).reshape((4,6))
生成布尔数组
a<10
把所有小于10的数取出来
a[a<10]
首先[]中的a<10生成布尔数组,然后最外层取出为TRUE的值,存入一维数组
筛选条件可以多个(&、|)
a[(a<5)|(a>7)]#不同的筛选条件必须用()隔开
4. 替换数组值
数据准备
a=np.random.randint(0,10,size=(2,5))
替换一个值或一种
a[3]=0#将第三行所有值都替换成0
a[a<3]=0#将所有小于三的数全都替换成零
替换两种,用where函数
where(条件,X,Y)
若不加X,Y,会返回两个数组,存储满足要求的元素的位置,第一个数组是行,第二个数组是列。
np.where(a<4,0,1)#把满足a<4的值替换成0,不满足的替换成1
数组计算(广播)
1. 数组和数
数据准备
a=np.random.randint(0,5,size=(3,5))
计算
a1=a*2
2. 数组和数组
- shape相同的数组
数据准备
b=np.random.randint(0,5,size=(3,5))
计算
c=a+b
加减乘除都一样
- shape不同的数组(和线代的差不多)
广播原则:
如果两个数组的后缘维度(从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为他们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
以二维数组为例
一个数组的行长度为1,列和另一个数组的某一维度一样,可进行计算
·(3,8,3)和(7,5) ×
·(3,8,3)和(3,8) ×
·(3,8,3)和(3,1) √
·(3,8,3)和(8,1) √
·(3,8,1)和(1,8) √
-括号里代表shape
数组形状操作
reshape、resize:
修改数组形状
reshape:返回修改结果
resize:直接在原数组内修改,不返回任何结果
flatten、revel
降维,把数组降成1维度
两个方法都不会直接在原数组内修改
不同在于返回值的拷贝问题
a=np.random.randint(1,9,(3,8))
print(a)
a1=a.flatten()
print(a1)
a1[0]=199
print(a)#a不发生任何变化
a=np.random.randint(1,9,(3,8))
print(a)
a1=a.ravel()
print(a1)
a1[0]=199
print(a)#a1中的第一个元素也就是a中的第一个元素被修改成199
flatten好像是复制数组到一块新内存
ravel好像是复制了数组的指针
数组叠加
- vstack 垂直方向的叠加
两个数组要列相同,列不相同会报错
shape x:(X,A)、y:(Y,A)
用法:
vstack1=np.vstack([x,y])#y拼接在了x的下面
vstack1=np.concatenate([x,y],axis=0)
- hstack 水平方向叠加
数组行要相同,行不相同会报错
shape x:(B,X)、y:(B,Y)
用法:
hstack1=np.hstack([x,y])#y拼接在了x的右面
vstack1=np.concatenate([x,y],axis=1)
- concatenate([数组],axis)
axis=0:垂直方向叠加,vstack(代码见vstack代码块)
axis=1:水平方向叠加,hstack(代码见hstack代码块)
axis=None:把两个数组拼接成一个一维数组(先扁平化),这里的数组不用管shape。
切割
split或array_split
split(数组,X,axis)
X:若是一个整数,就用该数平均切分,若是个数组([……]),为沿轴切分的位置
axis:
0:水平方向切割(行)
1:垂直方向切割(列)
转置
- x.T
x.dot(x.T):求内积 - x.transpose() 返回一个View
y=x.transpose()
对y的内容进行修改会改变x的值
深拷贝浅拷贝
浅拷贝
b=a.view()
对b的元素进行修改,也会影响a的元素
深拷贝
c=a.copy()
对c的元素进行修改,不会影响a的元素
降维函数:ravel是浅拷贝,flatten是深拷贝
csv文件操作
import csv
读
with open('xxx.csv',r) as fp:
reader = csv.reader(fp)
#reader是个迭代器
next(reader)#不要第一行,跳到第二行
for r in reader:
print(r)#r是个列表
以字典形式读:Dictreader
写
headers=['1','2','3']
views=[('张三',12,34),('李四',6,25),('王五',14,57)]
with open('xxx.csv',r,encoding='utf-8',newline='') as fp:
#newline='',去空行
writer = csv.writer(fp)
writer.writerrow(headers)
writer.writerrows(views)
以字典方式写入:Dictwriter
NAN,INF
NAN和INF
- NAN:Not A number 不是一个数字,但是属于浮点类型。
- INF:表示无穷大,属于浮点类型。inf:正无穷大,-inf:负无穷大。一般在除数为0的时候为无穷大。7/0。
NAN特点
- NAN和NAN不相等
np.NAN==np.NAN False - NAN和任何数做运算都是NAN
设置NAN值:
data=data.astype(np.float)#先确定数组的类型事浮点类型
data[1,2]=np.NAN
判断数组里的元素是不是NAN:
np.isnan(data)
处理缺失值:
- 删除缺失值
数据准备
data=np.random.randint(0,9,size=(3,5))
data=data.astype(np.float)#先确定数组的类型事浮点类型
data[1,2]=np.NAN
data[2,3]=np.NAN
(1)删除NAN元素
data[~np.isnan(data)]#取出所有不是NAN的值,删除NAN后,二维数组不完整了,就会成一维数组
(2)删除NAN元素的所在行
np.delete(data,lines,axis=0)
data:数组
lines:确定删除那几行or列
axis=0:行,axis=1:列
lines=np.where(np.isnan(data))[0]#[0]:取行,[1]:取列
np.delete(data,lines,axis=0)
- 用其他值代替NAN