一个在python中做科学计算的基础库,重在数值计算,也是大部分python科学技术库的基础库,多用在大型、多维数组上执行数值运算。
广播原则:
如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
可以把维度看成shape所对应的数字的个数。
import numpy as np # 一维数组 t1=np.arange(12) print(t1) print(t1.shape) # 二维数组 print('*'*50) t2=np.array([[1,2,3],[4,5,6]]) print(t2) print(t2.shape) # 三维数组 print('*'*50) t3=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) print(t3) print(t3.shape) # 改变数组的形状 reshape()返回新的数组 print('*'*50) t4=np.arange(12).reshape((3,4)) print(t4) print(t4.shape) print('*'*50) t5=np.arange(24).reshape((2,3,4)) print(t5) print(t5.shape) print('*'*50) # reshape(24,)和reshape(24,1)是两个不同的结果,一个是一维数组,由24个元素组成,一个是二维数组,每组只有一个元素 print(t5.reshape((24,))) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23] 这是一维数组 print(t5.reshape((24,1))) print(t5.reshape((1,24))) # [[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]] 这是二维数组 print('*'*50) # 多维维数组转成一维数组 t6=t5.reshape((t5.shape[0]*t5.shape[1]*t5.shape[2],)) print(t6) print(t6.shape) t7=t5.flatten() print(t7) print(t7.shape) print('*'*50) # 数组与数字进行运算,数组中的每个元素与数字做对应的运算 print(t5) print(t5+2) print(t5-2) print(t5*2) print(t5/2) # print(t5/0) # 其中0/0 得到的结果为nan not a number,非0/0 得到的结果是inf 无限 print('*'*50) # 相同形状的两个数组做数学运算,就是两个数组对应位置的元素做相应的运算 print(t5) t8=np.arange(100,124).reshape((2,3,4)) print(t5+t8) print(t5-t8) print(t5*t8) print(t5/t8) print('*'*50) # 一维数组中元素个数与多维数组中最后一个维度的元素个数相等,则进行相应的运算。 # 多维每一行对应的位置的元素与一维数组中对应的元素进行运算 相当于行对应位置运算 print(t5) t9=np.arange(1,5) # 一维数组 4个元素 [1 2 3 4] print(t9) print(t9.shape) print(t5+t9) print(t5-t9) print(t5*t9) print(t5/t9) print('*'*50) # 二维数组 多行一列情况中行的个数与多维数组中倒数第二个维度的数值相等,则进行相应的运算 # 二维数组中的元素与对应列位置上的元素进行运算,相当于列对应位置运算 print(t5) t10=np.arange(1,4).reshape((3,1)) # 二维数组,3行1列 print(t10) print(t10.shape) print(t5+t10) print(t5-t10) print(t5*t10) print(t5/t10) # 总结:数组与数组进行运算,要么数组的形状要么相同,要么行维度或列维度相同,否则不能进行运算。 (a,b,c)可以和(b,c)或(c,)或(b,1)进行运算
轴
在numpy中可以理解为方向,使用0,1,2...数字表示。对于一个一维数组,只有一个0轴,对于二维数组,有0轴和1轴,对于三维数组,有0,1,2轴。
csv:comma-separateed value,逗号分隔值文件
显示:表格状态
源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录。
import numpy as np ''' fname:文件、执法车或产生器、可以是压缩文件 dtype:数据类型。可选,csv的字符串以什么数据类型读入数组中。默认np.float delimeter:分隔字符串,默认是任何空格 skiprows:跳过多少行,一般跳过第一行表头 usecols:读取指定的列,索引。元组类型 unpack:转置。如果为True,读入属性将分别写入不同数组变量,False 读入数据只写入一个数组变量。默认为False ''' f=np.loadtxt(fname='./**.csv',dtype='int',delimiter=',',skiprows=0,usecols=None,unpack=False) print(f)
转置
转置是一种变换,对于numpy中的数组来说,就是在对角线方向交换数据,目的是为了更方便的去处理数据。
转置三种方式:
1,T属性 t.T
2,transpose()方法 t.tanspose()
3,swapaxes()方法 t.swapaxes(1,0)
import numpy as np t1=np.arange(24).reshape(4,6) print(t1) print('*'*50) # 方法一:T属性 t2=t1.T print(t2) # 方法二:transpose()方法 print('*'*50) t3=t1.transpose() print(t3) print('*'*50) # 方法三:swapaxes()方法 t4=t1.swapaxes(1,0) print(t4)
索引和切片
import numpy as np a=np.arange(12).reshape(3,4) print(a) print('*'*50) # 取某一行 print(a[1]) #[4 5 6 7] print('*'*50) # 取多行 print(a[0:2]) print('*'*50) # 取指定行 print(a[[0,2]]) print('*'*50) # 取一列 print(a[:,1]) print('*'*50) #取多列 print(a[:,1:3]) print('*'*50) # 取指定列 print(a[:,[0,2]]) print('*'*50) # 取第一行第二列的数据 print(a[0,1]) print('*'*50) # 取多行多列 第二行到第三行,第二列到第四列 [1:3) [1:4) print(a[1:3,1:4]) print('*'*50) # 取不相邻的点 取得(1,0)和(2,2)两个位置上的数据 print(a[[1,2],[0,2]])
修改值
import numpy as np t=np.arange(12).reshape(3,4) print(t) print('*'*50) # 将第一行至第三行的数据赋值为100 t[1:3,]=100 print(t) print('*'*50) # 将第一列和第二列的数据赋值为200 t[:,0:2]=200 print(t) print('*'*50) # 将(1,2)和(2,4)位置上数据赋值为300 t[[1,2],[2,3]]=300 print(t) print('*'*50) # t<10 的结果 元素小于10则值为True,反之为False print(t<10) ''' [[False False True True] [False False False False] [False False False False]] ''' print('*'*50) # t[t<10] 的结果 数组中符合条件的数据 print(t[t<10]) print(type(t[t<10])) # <class 'numpy.ndarray'> print('*'*50) # 将数组中数值大于200的元素数据改为210 t[t>200]=210 print(t) print('*'*50) # 三元运算符 np.where(t>200,250,100) 数组中大于250的数据改为250,反之改为100 t1=np.where(t>200,250,100) # 有返回值 print(t1) print('*'*50) # 裁剪clip() t.clip(100,200) 小于100的替换为100,大于200的替换为200 print(t) t2=t.clip(80,208) print(t2)
数组的拼接
import numpy as np t1=np.arange(10).reshape(2,5) t2=np.arange(20,30).reshape(2,5) # 数组横向拼接 print(t1) ''' [[0 1 2 3 4] [5 6 7 8 9]] ''' print(t2) ''' [[20 21 22 23 24] [25 26 27 28 29]] ''' print('*'*50) # 数组纵向拼接(vertical) np.vstack() t3=np.vstack((t1,t2)) print(t3) ''' [[ 0 1 2 3 4] [ 5 6 7 8 9] [20 21 22 23 24] [25 26 27 28 29]] ''' print('*'*50) # 数组横向拼接(Horizonta) np.hstack() t4=np.hstack((t1,t2)) print(t4) ''' [[ 0 1 2 3 4 20 21 22 23 24] [ 5 6 7 8 9 25 26 27 28 29]] ''' print('*'*50) t6=np.arange(6).reshape((2,3)) t7=np.arange(9).reshape((3,3)) t8=np.arange(8).reshape((2,4)) print(t6) print(t7) print(t8) print('*'*50) t9=np.vstack((t6,t7)) t10=np.hstack((t6,t8)) print(t9) ''' [[0 1 2] [3 4 5] [0 1 2] [3 4 5] [6 7 8]] ''' print(t10) ''' [[0 1 2 0 1 2 3] [3 4 5 4 5 6 7]] ''' # 总结:纵向拼接(np.vstack()) 要求两个数组的列的个数一致;横向拼接(np.hstack()) 要求两个数组的行的个数一致
数组的行列交换
import numpy as np t=np.arange(20).reshape(4,5) print(t) print('*'*50) # 行交换 相当于第三行的数据赋值给第一行,第一行的数据赋值给第三行 t[[0,2],:]=t[[2,0],:] print(t) print('*'*50) # 列交换 相当于第二列的数据赋值给第一列,第一列的数据赋值给第二列 t[:,[0,1]]=t[:,[1,0]] print(t) # 总结:原理还是赋值
常见方法
import numpy as np import random # 创建一个全是0的数组 np.zeros() t1=np.zeros((3,4)) print(t1) print('*'*50) # 创建一个全是1的数组 np.ones() t2=np.ones((3,4)) print(t2) print('*'*50) # 创建一个对角线为1的正方形数组(方阵)np.eye() t3=np.eye(3) print(t3) print('*'*50) # 获取最大值或最小值的位置 t=np.array([random.randint(10,50) for _ in range(24)]).reshape(4,6) print(t) t_max_index=np.argmax(t,axis=0) print(t_max_index) t_min_index=np.argmin(t,axis=1) print(t_min_index)
numpy生成随机数
import numpy as np #rand(d0,d1...dn) 创建d0-dn维度的均匀分布的随机数数组,浮点数。范围从0到1 t=np.random.rand(3,4) print(t) print('*'*50) # randn(d0,d1...dn) 创建d0~dn维度的标准正态分布随机数,浮点数。平均数0,标准差为1 t1=np.random.randn(3,4) print(t1) print('*'*50) #randint(low,high,(shape)) 从给定上下限范围选区随机数整数。范围是low,high.形状是shape t2=np.random.randint(10,20,(3,4)) print(t2) print('*'*50) # uniform(low,high,(size)) 产生具有均匀分布的数组,low是起始值,high是结束值。size形状 t3=np.random.uniform(1,10,(3,4)) print(t3) print('*'*50) # normal(loc,scale,(size)) 从指定正态分布中随机抽取样本,分布中心是loc(概率分布的均值),标准差为scale,形状是size。 t4=np.random.normal(1.0,0.8) print(t4) print('*'*50) # seed(s) 随机数种子,s是给定的种子值,因为计算机生成的是伪随机数,所以设定相同的随机数种子,可以每次生成相同的随机数。 np.random.seed(10)
import numpy as np # a=b 完全不复制,a和b相互影响 t1=np.arange(10).reshape(2,5) t2=t1 print(t1) print(t2) print('*'*50) t1[:,[0,1]]=100 print(t1) print(t2) # a=b[:] 视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,它们两个的数据变化是一致的。 print('*'*50) t3=t1[:,1:3] print(t3) t3[0,[0,1]]=500 print(t1) print(t2) print(t3) # a=b.copy(),复制,a和b操作互不影响 print('*'*50) t4=t1.copy() t4[0,[0,1]]=600 print(t4) print(t1)
nan和inf
nan(NAN,Nan):not a number表示不是一个数字。
inf(-inf,inf):infinity,inf表示正无穷,-inf表示负无穷。一个数字除以0,则会出现inf(python中直接会报错,numpy中是一个inf或-inf)
import numpy as np #False 两个nan是不相等的 print(np.nan==np.nan) a=np.nan b=np.inf print(type(a),type(b)) #<class 'float'> nan,inf的数据类型都是float t1=np.arange(12).reshape((3,4)).astype(float) print(t1) # np.count_nonzero(t)查询数组中非0值的个数 print(np.count_nonzero(t1)) print('*'*50) t1[2,2:]=np.nan print(t1) print(t1[t1!=t1]) # [nan nan] 根据两个nan不相等,则可以查询一个数组中nan值 # np.count_nonezero(t!=t) 判断出数组中nan的个数 或者t!=t 用np.isnan(t)替换 或者上述中len(t1[t1!=t1])获取 print(np.count_nonzero(t1!=t1)) # 2 print('*'*50) # 修改数组中nan值为0 # 方法一:t1[t1!=t1]=0 #t1[t1!=t1]=0 # 方法二:t1[np.isnan(t1)]=0 t1[np.isnan(t1)]=0 print(t1) # 总结:t!=t 或np.isnan(t) 结果是一样的
处理数组中的nan值,可以替换为0(不推荐),也可以替换为均值或中值或者直接删除含有nan的一行数据。
import numpy as np # 将数组中所有列上为nan的值改为平均数 def fill_ndarray(t): for i in range(t.shape[1]): t_cols = t[:, i] # 获取数组中列数据 nan_count = np.count_nonzero(t_cols != t_cols) # 获取值为nan的元素个数 if nan_count != 0: non_nan_cols = t_cols[t_cols == t_cols] # 获取除去nan值之外的数据,数组 t_col_mean = np.mean(non_nan_cols) # 获取非nan数据的平均值 t_cols[np.isnan(t_cols)] = t_col_mean # 将值为nan的元素赋值为平均值 if __name__ == '__main__': t = np.arange(12).reshape(3, 4).astype('float') print(t) t[2, :] = np.nan # 赋值nan print(t) fill_ndarray(t) print(t)

posted on
浙公网安备 33010602011771号