Python Numpy
一、numpy简介 NumPy(Numerical Python) 是Python语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也征地数组运算提供大量的数据函数库 NumPy的前身Numeric最早是由Jim Hugunin与其它写作者共同开发,2005年,Travis Oliphant在Numberic中结合了另一个同性质的程序库Numarray的特色,并加入了其它扩展而开发了NumPy。NumPy为开放源代码并且由多协作者共同维护开发。 作用: NumPy是一个运行速度非常快的数学库,主要用于数组计算 包含: 1.一个强大的N维数组对象ndarray 2.广播功能函数 3.整合C/C++/Fortran代码的工具 4.线性代数、傅里叶变换、随机数生成等功能 优势: 1.对于同样的数值计算任务,使用NumPy要比直接编写Python代码便捷的多 2.numpy中的数组的存储效率和输入输出性能均远远优于Python中等价基的基本数据结构,且其能够提升性能是与数组中的元素成比例的 3.numpy的大部分代码都是用C语言写的,其底层算法在涉及的时就有着优异的性能,这使得numpy比纯Python代码高效得多 应用: NumPy通常与SciPy(Scientfic Python)和Matplotlib(会图库)一起使用,这种组合官方用于代替MatLib,是一个强大的科学计算环境,有助于我们通过Python学习数据科学或者机器学习 SciPy: 是一个开源的Python算法库和数据工具包 包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、型号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算 Matplotlib: 是Python编程语言及其数值数学扩展包NumPy的可视化操作界面。它为利用通用的图形用户界面工具包,如:Tkinter,wxPython,Qt或GTK+向应用程序嵌入式绘图提供了应用程序接口(API) 安装: pip install numpy
二、Ndarray对象介绍 1.介绍: ① NumPy最重要的一个特点就是其N维数组对象ndarray,它是一系列同类型数据的集合,以0下标为开始进行集合中元素的索引 ② ndarray对象是用于存放同类型元素的多维数组 ③ ndarray中的每个元素在内存中都有相同存储大小的区域 ④ 组成部分 .一个指向数据(内存或内存映射文件中的一块数据)的指针 .数据类型或dtype,描述在数组中的固定大小值的格子 .一个表示数组形状(shape)的元组,表示各维度大小的元组 .一个跨度元组(stride),其中的证书指的是为了前进到当前维度下一个元素需要“跨过”的字节数
三、numpy数据类型 1.数据结构 numpy支持的数据类型比Python内置的类型要多很多,基本上可以和C语言的数据类型对应上,其中部分类型对应为Python内置的类型 numpy的数值类型实际上是dtype对象的实例,并对应唯一的字符,包括np.bool_,np.int32,no.float32,等等 bool_ 布尔型数据类型(True或者False) int_ 默认的整数类型(类似于C语言中的long,int32或int64) intc 与C的int类型一样,一般是int32或int64 intp 用于索引的整数类型(类似于C的ssize_t,一般情况下仍然是int32或者int64) int8 字节(-128 to 127) int16 整数(-32768 to 32767) int32 整数(-2147483648 to 2147483647) int64 整数(-9223372036854775808 to 9223372036854775807) uint8 无符号整数(0 to 255) uint16 无符号整数(0 to 65535) uint32 无符号整数(0 to 4294967295) uint64 无符号整数(0 to 18446744073709551615) float_ float64类型的简写 float16 半精度浮点数,包括:1个符号位,5个指数位,10个尾数位 float32 半精度浮点数,包括:1个符号位,8个指数位,23个尾数位 float64 半精度浮点数,包括:1个符号位,11个指数位,52个尾数位 compulex_ complex128类型的简写,即128位复数 complex64 复数,标识双32位浮点数(实数部分和虚数部分) complex128 复数,标识双64位浮点数(实数部分和虚数部分) 每个内建类型都有一个唯一定义它的字符代码 b 布尔型 i 有符号整型 u 无符号整型integer f 浮点型 c 复数浮点型 m timedelta(事件间隔) M datetime(日期时间) O Python 对象 S,a 字节串,字符串 U Unicode V 原始数据(Void) 2.数据类型对象(dtype) 数据类型对象是用来描述与数组对应的内存区域如何使用,这依赖如下几个方面: .数据的类型(整数,浮点数或者Python对象) .数据大小(例如,整数使用多少个字节存储) .数据的字节顺序(小端法或者大端法)【通过对数据类型预选设定"<"或">"来决定的。"<"意味着小短发(最小值存储在最小的地址,即低位组放在最前面)。">"意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面)】 .在结构化类型的情况下,字段的名称、每个字段的数据类型和每个字段所取的内存块的部分 .如果数据类型是子数组,它依赖它的形状和数据类型 3.创建数据类型对象 原型:numpy.dtype(object, align, copy) 参数:odject要转换为的数据类型对象。align如果为true,填充字段使用其类似C的结构体。copy赋值dtype对象,如果为false,则是对内置数据类型对象的引用
import numpy dt1 = numpy.dtype(numpy.int32) dt2 = numpy.dtype('int32') dt3 = numpy.dtype('i4') # 4代表4个字节int型也就是int32,int64就是i8 dt4 = numpy.dtype('<i4') # 小端int32 print(dt1,dt2,dt3,dt4) print(type(dt1),type(dt2),type(dt3),type(dt4)) import numpy student = numpy.dtype([('name','S20'),('age','i4'),('marks','f4')]) # 自定义数据类型 print(student) print(type(student)) # 创建数组 b = numpy.array([('zhangsan',18,100),('lisi',19,99),('wangwu',20,120)],dtype=student) print(b['name']) print(b[0]['name'])
4.将数据保存到文件
import numpy nd1 = numpy.random.randint(0,100,size=(3,5)) nd2 = numpy.random.randn(3,5) print(nd1,nd2) # 把一个数据存储在文件中 numpy.save('./data',nd1) # 默认后缀.npy # 加载数据 nd3 = numpy.load('./data.npy') print(nd3) # 多个文件保存在文件中。默认.npz后缀 numpy.savez('./data.npz', a=nd1, abc=nd2) # 保存数据a,abc为key,取数据的时候需要用到 data = numpy.load('./data.npz') print(data['a'], data['abc']) # 压缩保存 numpy.savez_compressed('./data1.npz', x=nd1, y=nd2) data=numpy.load('./data1.npz') print(data['x']) # 保存txt,可以直接读取 numpy.savetxt(fname='./data.txt', X=nd1, fmt='%0.2f',delimiter=',') data = numpy.loadtxt(fname='./data.txt',delimiter=',')
四、创建Ndarray数组对象 说明: numpy默认ndarray的所有元素的类型是相同的,这一点与Python中的list不同 如果传进来的列表中包含不同的类型,则统一为同一类型,优先级str>float>int 也就是同时存在str和int时,统一使用str类型 array()函数 原型:numpy.array(object, dtype=None,copy=True,order=None,subok=False,ndmin=0) 作用:创建Ndarray数组对象 参数: 1.object 数组或嵌套的数列 2.dtype 数组元素的数据类型,可选 3.copy 对象是否需要复制,可选 4.order 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认) 5.subok 默认返回一个与基类类型一致的数组 6.ndmin 指定生成数组的最小维度 例子:
import numpy arr = numpy.array([1,2,3,4,5]) # 一维数组,列表参数 arr = numpy.array((1,2,3,4,5)) # 一维数组,元组参数 arr = numpy.array([[1,2,3],[3,4,5]]) # 多维数组 arr = numpy.array([1,2,3,4,5,6,7],ndmin=2) # 规定为二维数组 arr = numpy.array([1,2,3,4,5,6,7],dtype=numpy.int32) # dtype指定元素类型 student = numpy.dtype([('name','S20'),('age','i4'),('marks','f4')]) # 自定义数据类型 arr = numpy.array([('zhangsan',18,100),('lisi',19,99),('wangwu',20,120)],dtype=student) # 自定义熟路类型
asarray()函数 原型:numpy.asarray(a, dtype=None, order=None) 作用:类似numpy.array,但numpy.asarray只有三个参数。一般用于数组元素类型转换 参数: 1.a 任意形式的输入参数,可以是列表、列表的元组、元组、元组的元组、元组的列表、多维数组 2.dtype 数据类型,可选 3.可选,有“C”和“F”两个选项,分别代表,行优先和列优先,在计算机内存中存储袁术的顺序 empty()函数 原型:numpy.empty(shape, dtype=float, order="C") 作用:创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组 参数: 1.shape 数组形状 2.dtype 数据类型,可选 3.order 可选,有“C”和“F”两个选项,分别代表,行优先和列优先,在计算机内存中存储袁术的顺序 zeros()函数 原型:numpy.zeros(shape, dtype=float,order="C") 作用:创建指定大小的数组,数组元素以0来填充 参数: 1.shape 数组形状 2.dtype 数据类型,可选 3.order 可选,有“C”和“F”两个选项,分别代表,行优先和列优先,在计算机内存中存储袁术的顺序 ones()函数 原型:numpy.ones(shape, dtype=float,order="C") 作用:创建指定大小的数组,数组元素以1来填充 参数: 1.shape 数组形状 2.dtype 数据类型,可选 3.order 可选,有“C”和“F”两个选项,分别代表,行优先和列优先,在计算机内存中存储袁术的顺序 full()函数 原型:numpy.ones(shape, full_value, dtype=float,order="C") 作用:创建指定大小的数组,数组元素以1来填充 参数: 1.shape 数组形状 2.full_value 以什么值作为默认值 3.dtype 数据类型,可选 4.order 可选,有“C”和“F”两个选项,分别代表,行优先和列优先,在计算机内存中存储袁术的顺序 eye()函数 原型:numpy.eye(N, M=None, k=0, dtype=float, order="C") 作用:对角线为1其他的位置为0 参数: 1.N 行数量 2.M 列数量,默认等于行数量,可选 3.dtype 数据类型,可选 4.order 可选,有“C”和“F”两个选项,分别代表,行优先和列优先,在计算机内存中存储袁术的顺序 arange()函数 原型:numpy.arange(start, stop, step, dtype) 作用:创建数值方位并返回ndarray对象,根据start与stop指定的范围以及step设定的补偿,生成一个ndarray 参数: 1.start 起始值,默认为0 2.stop 终止值(不包含) 3.step 步长,默认为1 4.dtype 返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型 frombuffer()函数 原型:numpy.frombuffer(buffer, dtype=float,count=-1,offset=0) 作用:用于实现动态数组,接受buffer输入参数,以流形式读入转化成ndarray对象 注意:buffer是字符串的时候,Python3默认str是Unicode类型,所以要转成bytestring在源str前加上b 参数: 1.buffer 可以是任意对象,会以流的形式读入 2.dtype 返回数组的数据类型,可选 3.count 读取的数据数量,默认为-1,读取所有数据 4.offset 读取的起始位置,默认为0 import numpy a = b'hello abcdef' # 从a字符串的下标为2开始读取5个S1数据。S1代表长度为1的字符串。 arr = numpy.frombuffer(a,dtype="S1",count=5,offset=2) fromiter()函数 原型:numpy.fromiter(iterable,dtype,count=-1) 作用:从可迭代对象中建立ndarray对象,返回以为数组 参数: 1.iterable 可迭代对象 2.dtype 返回数组的数据类型,可选 3.count 读取的数据数量,默认为-1,读取所有数据 import numpy x = [1,2,3,4] z = iter(x) arr = numpy.fromiter(z, dtype='i2') linspace()函数 原型:numpy.linsace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) 作用:创建一个以为数组,数组是一个等差数列构成 参数: 1.start 序列的起始值 2.stop 序列的终止值,如果endpoint为true,该值包含于数列中 3.num 要生成的等步长的样本数量,默认为50 4.endpoint 该值为true时,数列中包含stop值,反之不包含,默认是true 5.retstep 如果为true时,生成的数组中会显示间距,反之不显示 6.dtype ndarray的数据类型 logspace()函数 原型:numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None) 作用:创建一个等比数列 参数: 1.start 序列的起始值 2.stop 序列的终止值,如果endpoint为true,该值包含于数列中 3.num 要生成的等步长的样本数量,默认为50 4.endpoint 该值为true时,数列中包含stop值,反之不包含,默认是true 5.base 对数log的底数,默认是10 6.dtype ndarray的数据类型 random.rand()函数 原型:rand(d0, d1, ..., dn) 作用:生成0到1之间的随机数。 参数:生成一维数组就是一个参数,二维就是两个参数,三维就是三个参数……以此类推。不传就是生成一个0到1的随机数 random.random()函数 原型:random(size=None) 作用:生成0到1之间的随机数。和rand一样,只不过参数用size接收 参数:size生成一维数组就是一个参数,二维就是两个参数,三维就是三个参数……以此类推。不传就是生成一个0到1的随机数 random.randint()函数 原型:numpy.random.randint(low, high=None, size=None, dtype=int) 作用:生成随机整数 参数: 1.low 包含的下限 2.high 不包含的上限 3.size 元素个数,支持多维,如:(3,2)两行3列 4.dtype 元素类型 random.randn()函数 原型:numpy.random.randn(d0, d1, ..., dn) 作用:返回一个或一组样本,具有标准正态分布。也就是生成一组数值,差值为1 标准正太分布:又称为u分布,是以0位均值、以1位标准差的正太分布,记为N(0,1) random.normal()函数 原型:numpy.random.normal(loc=0.0, scale=1.0, size=None) 作用:生成高斯分布的概率密度随机数 参数: 1.loc 浮点数,次概率分布的均值(对应这整个分布的中心centre) 2.scale 浮点数,次概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高) 3.size 输出的shape,默认为None,只输出一个值
五、Ndarray数组属性 简介:NumPy数组的维度称为秩(rank),一维数组的秩为1,二维数组的秩为2,以此类推在NumPy中,每一个现行的数组称为一个轴(axis),也就是维度(dimensions)。比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一堆数组就是NumPy中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量--秩,就是数组的维度 很多时候可以声明axis。axis=0,标识沿着第0轴进行操作,即对每一列进行操作;axis=1,标识沿着第1轴进行操作,即对每一行进行操作 常用属性: 1.ndim 秩,即轴的数量或者维度的数量 2.shape 数组的维度,对于举证,n行m列。你可以直接修改它,也可以通过reshape重新设置它 3.size 数组元素的总个数,相当于shape中n*m的值。 4.dtype ndarray对象的元素类型 5.itemsize 每个元素的大小,以字节为单位 6.flags ndarray对象的内存信息。其对应值的意思: C_CONTIGUOUS : True # 数据是在一个单一的C风格的连续段中 F_CONTIGUOUS : True # 数据是在一个单一的Fortran风格的连续段中 OWNDATA : True # 数组拥有它所使用的内存或从另一个对象中借用它 WRITEABLE : True # 数据区域可以被写入,将该值设置为False,则数据为只读 ALIGNED : True # 数据和所有元素都适当地对齐到硬件上 WRITEBACKIFCOPY : False# 这个数组是其他数组的一个副本,放这个数组被释放时,源数组的内容将被更新 7.real ndarray元素的实部 8.imag ndarray元素的虚部 9.data 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性
六、数组索引、切片 1.基本索引和切片
a = numpy.random.randint(0,30,size=10) a[3] # 取一个 a[[1,3,5]] # 取多个 a[0:3] # 左闭右开取的:0,1,2 a[:3] # 与a[0:3]相同 a[5:9] # 从某个索引开始切片:5,6,7,8 左闭右开 a[5:] # 冒号后面不写内容,那么默认就是到最后 a[3::3] # 从索引3开始,每三个数取一个(从左到右取第一个) a[::-1] # 倒着数,数组进行了颠倒 a[::-2] # 倒着数,每两个取一个(从右到左取第一个) a[5::-3] # 倒着数,从下标5开始到0结束,包含5,每三个取一个(从右到左取第一个) a[1:7:2] # 从下标1开始到下标7(左闭右开不包含7),每两个取一个 # 二维数组切片 b = numpy.random.randint(0,30,size=(10,10)) b[1] # 取第2行 b[[0,3,5]] # 取1,4,6行 b[1,1] # 取第2行第2列的数 b[3,[2,5,6]]# 取第4行的3、6、7列 b[2:7,1::3] # 取2到7行(不含7行),1到最后列,每3个取一个(从左到右取第一个) b[2::7,1::3]# 从第2行到最后一行,每7行取一行(从左到右取第一个),从第1到最后列,每3个取一个(从左到右取第一个) b[-1,-1] # 取最后一行最后一列的元素 b[-2,[-2,-3,-4]] # 取最后一列的倒数第2,3,4列的元素
2.花式索引和索引技巧
import numpy a = numpy.arange(20) # 值为1,2,3……19的值 b = a[3:7] # 注意:这种普通切片不是深拷贝 c = a[[1,3,4,5]] # 在索引是给一个数组,这中方式就是花式索引。属于深拷贝 a = numpy.random.randint(0, 151, size=(2, 3)) cond = a >= 100 # 这里对每个元素进行比较生成一个2行3列的结果集 # a本身就是2行3列的二维数组,以同样2行3列的bool值数组作为索引,它会返回值为True的元素 a[[[True,False, False],[True,False, False]]] a[cond] # 用结果集去找数据。同理:a[[[True,False, False],[True,False, False]]] a[[True,False]] # 同理将a看成一维数组,取为True的元素 a = numpy.random.randint(0, 151, size=(100, 3)) cond = a >= 100 cond2 = cond[:,0]*cond[:,1]*cond[:,2] # 返回三列都为真的一维数组 a[cond2] # 取出3列值都100的行。
3.迭代 numpy.nditer基本使用 简介:它是一个有效的多维迭代器对象,可以用在数组上进行迭代。数组每个元素可以使用Python的标准Iterator接口来访问。不是使用标准C或者Fortran顺序,选择的顺序是和数组内存布局一直的,这样做是为了提升访问效率,默认是行序优先(row-mahor order,或者说是C-order)反映了默认情况下秩序访问每个元素,而无需考虑其特定顺序。可以通过迭代上述数组的转置来看到这一点,并与以C顺序访问数组转置的copy方式做对比。 广播迭代:如果两个数组是可广播的,nditer组合对象能够同时迭代它们。假设数组a具有维度3×4,并且存在维度1×4的另一个数组b,则使用一下类型的迭代器(数组b被广播到a的大小) 原型构造函数:nditer(op, flags=None, op_flags=None, op_dtypes=None, order='K', casting='safe', op_axes=None, itershape=None, buffersize=0) 参数: ① op 需要迭代的数据 ② flags 'c_index' 和order='C'一样;'f_index'和order='F'一个意;'multi-index'每次迭代可以跟踪一种索引类型;'external_loop' 给出的值是具有多个值的一维数组,而不是0维数组 ③ op_flags 必须指定“readonly”、“readwrite”或“writeonly”。 “readonly” 表示操作数只能从中读取。 “readwrite” 表示操作数将被读取和写入。 “writeonly” 表示操作数将仅写入。 “no_broadcast” 阻止广播操作数。 “contig” 强制操作数数据是连续的。 “aligned” 强制对齐操作数数据。 “nbo” 强制操作数数据采用本机字节顺序。 “copy” 允许在需要时进行临时只读复制。 “updateifcopy” 允许在需要时进行临时读写复制。 “allocate” 如果数组在“op”参数中为“None”,则“allocate”会导致数组被分配。 “no_subtype” 防止“allocate”操作数使用子类型。 “arraymask” 表示此操作数是在写入设置了'writemasked'标志的操作数时用于选择元素的掩码。迭代器不强制执行此操作,但当从缓冲区写回数组时,它只复制此掩码指示的元素。 “WriteMask” 表示仅写入所选“arraymask”操作数为True的元素。 “overlap_aspect_elementwise” 可用于标记仅按迭代器顺序访问的操作数,以允许在存在“copy_if_overlap”时进行较保守的复制。 ④ op_dtypes ndarray数据类型 ⑤ order {'C', 'F', 'A', 'K'}。C是最后一个索引变化最快。F是第一个索引变化最快。A是C或F中的一种,也就说也与索引相关。K按内存存储顺序来。 ⑥ casting ⑦ op_axes ⑧ itershape ⑨ buffersize
import numpy as np a = np.arange(12).reshape(3,4) print('原顺序:',a, end='\n\n') # a.T 是对a进行转秩,也就是行列置换 for x in numpy.nditer(a.T): print(x, end=', ') print('\n-------------------------------------------\n') b = a.T.copy(order='C') for x in numpy.nditer(b): print(x, end=', ') # 通过上面遍历发现,a和a.T遍历的结果没有什么区别 # 可以得出结论:a.T转秩后并没有改变它的内存存储顺序 print('\n-------------------------------------------\n') # order取F代表列优先,C代表行优先,op_flags=['readwrite']意思是迭代的元素是可修改的 for x in numpy.nditer(a, order='F', op_flags=['readwrite']): x[...] = x * 2 print(a) print('\n-------------------------------------------\n') a = np.arange(12).reshape(3,4)
七、数组运算 1.广播 ① 简介:广播是numpy对不同形状(shape)的数组进行数值计算的方式,对数组的算术运算通常在相应的元素上进行。 ② 形状相同:如果两个数组a和b形状相同,即满足a.shape==b.shape,那么a+b的结果就是a与b数组对应下标位相加。这要求维数相同,且各维度的长度相同。 ③ 形状不同:如果两个数组的维数不相同,则元素到元素的操作是不可能的。然而,在numpy中仍然可以对形状不同的数组进行操作,因为它拥有广播功能。较小的数组会广播到较大数组的大小,以便使它们的形状可以兼容。 ④ 广播规则: .让所有输入的数组都向其中形状最长的数组看起,形状中不足的部分通过在前面加1补齐 .输出数组的形状是输入数组形状的各个维度上的最大值 .如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为1时,这个数组能够用来计算,否则出错 .当输入数组的某个维度的长度为1时,沿着此维度运算时都用此维度上的第一组值 ⑤ 简单理解:对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足: .数组拥有相同形状 .当前维度的值相等 .当前维度的值有一个是1 若条件不满足:抛出"ValueError:frames are not aligned"异常 2.常规运算
# 加减乘除指数幂运算 # 计算出的结果,返回新的数组 import numpy nd1 = numpy.random.randint(0,10,size=5,dtype=numpy.int8) nd2 = numpy.random.randint(0,10,size=5,dtype=numpy.int8) print(nd1,nd2) # + print(nd1+1) print(nd1+nd2) # - print(nd1-1) # × print(nd1*2) print(nd1*nd2) # / print(nd1/2) print(nd1/nd2) # 幂运算 print(nd1**2) print(numpy.power(2,3)) # 2的3次方 print(nd1**nd2) print(numpy.power(nd1,nd2)) # 意思和“nd1**nd2”相同 # 对数运算 a = numpy.log(100) # 底数是自然数e 2.718(e是自然对数的底数,是一个无限不循环小数,其值是2.71828……,它是: 当n趋向∞时,(1+1/n)^n的极限值。) print(a) b = numpy.log10(1000) # 10的3次方等于1000,所以得到的结果是3 c = numpy.log2(1024) # 2的10次方等于1024 print(b,c)
3.逻辑运算
import numpy nd1 = numpy.random.randint(0,10,size=5,dtype=numpy.int8) nd2 = numpy.random.randint(0,10,size=5,dtype=numpy.int8) # 数组中的每一个同下标元素进行对比后的结果,形成bool值数组 print(nd1>nd2) print(nd1>=nd2) print(nd1<nd2) print(nd1<=nd2) print(nd1==nd2) print(nd1!=nd2)
4.数组与标量计算
import numpy nd1 = numpy.random.randint(0,10,size=5,dtype=numpy.int8) nd2 = numpy.random.randint(0,10,size=5,dtype=numpy.int8) print(nd1+10) print(nd1-1) print(nd1*2) print(nd1/2) print(2/nd1) # 分母不能为0
5.-=、+=、*=直接改变源数组
import numpy nd1 = numpy.random.randint(0,10,size=5,dtype=numpy.int8) nd2 = numpy.random.randint(0,10,size=5,dtype=numpy.int8) print(nd1) nd1+=1 print(nd1) nd1-=1 print(nd1) nd1*=2 print(nd1) # nd1/=1 # 除等是不支持的
八、复制和视图 1.完全没有复制
a = numpy.random.randint(0,10,size=5) b=a # 这种赋值后,a和b改的都是同一个内容 print('a id:',id(a)) print('b id:',id(b)) print('a[0] id:',id(a[0])) print('b[0] id:',id(b[0]))
2.视图、查看或者浅拷贝
a = numpy.random.randint(0,10,size=5) b=a.view() # 元素地址并没有变化 print('a id:',id(a)) print('b id:',id(b)) print('a[0] id:',id(a[0])) print('b[0] id:',id(b[0]))
3.深拷贝
a = numpy.random.randint(0,10,size=5) b=a.copy() # 元素也是新分配的内存。 print('a id:',id(a)) print('b id:',id(b)) print('a[0] id:',id(a[0])) print('b[0] id:',id(b[0])) # 数据量大的时候是这么操作的 a = numpy.arange(1e8) # 这里有1亿个元素 b = a[[1,2,3,4,5,6,7]].copy() # 取其中需要用的数据 del a # 将用不到的数据清空掉
九、修改数组形状 reshape()函数 原型:ndarray.reshape(shape, order='C') 作用:不改变数据的条件下修改形状 参数:shape形状。order 'C'按行,'F'按列,'A'原顺序,'K'元素内存顺序 flatten()函数 原型:ndarray.flatten(order='C') 作用:展平的数组元素组并拷贝一份,顺序通常是"C风格" 注意:修改返回的数组不会对源数组产生影响 参数:order 'C'按行,'F'按列,'A'原顺序,'K'元素内存顺序 ravel()函数 原型:ndarray.ravel(order="C") 作用:展平的数组元素,顺序通常是“C风格”,返回的是数组视图(view,有点类似C/C++应用的reference的意味) 注意:修改会影响原始数组,order="F"的时候不会影响源数组 transpose()函数 原型:numpy.transpose(a, axes=None) 作用:对换数组的维度,行列转换 注意:修改会影响原始数组 参数:a 要操作的数组,axes 整数列表,对应维度,通常所有维度都会对换 ndarray.T 属性 类似numpy.transpose rollaxis()函数 原型:numpy.rollaxis(a, axis, start=0) 作用:向后滚动特定的轴到一个特定的位置 参数:a 要操作的数组。axis 向后滚动的轴,其他轴的对应位置不会改变。start 默认为0,标识完整的滚动,会滚动到特定位置(axis=2、start=0、shape=(2,3,4,5),将2轴移动到0轴,其他轴往后滚动,shape=(4,2,3,5))。 swapaxes()函数 原型:numpy.swapaxes(a, axis1, axis2) 作用:交换数组的两个轴 参数:a 要操作的数组。axis1和axis要替换的两个轴。如:axis1=2、axis1=0、shape=(2,3,4,5),结果是shape=(4,3,2,5))。 numpy.broadcast 对象 作用:用于模仿广播的对象,它返回一个对象,该对象封装了将一个数组广播到另一个数组的结果
import numpy x = numpy.array([[1],[2],[4]]) y = numpy.array([4,5,6]) print('原始x:',x, end="\n\n") print('原始y:',y, end="\n\n") b = numpy.broadcast(x,y) # 返回一个广播对象 print(b.shape) # 广播之后是3×3 print('广播对象b:',b) print('广播对象具有iterator属性,基于自身组件的迭代器元组:') r, c = b.iters print(next(r), next(c)) # 广播之后是3×3所以可以拿9次值 print(next(r), next(c)) print(next(r), next(c)) print(next(r), next(c)) print(next(r), next(c)) print(next(r), next(c)) print(next(r), next(c)) print(next(r), next(c)) print(next(r), next(c)) b = numpy.broadcast(x,y) # 返回一个广播对象 c = numpy.empty(b.shape, dtype='i4') # 创建一个相同维度的 c.flat = [u+v for (u,v) in b] # 获取它的值 print(c) # 和print(x+y)值一样
broadcast_to()函数 原型:numpy.broadcast_to(array, shape, subok=False) 作用:将数组广播到新形状。它在原始数组上返回只读视图。它通常不连续。如果新形状不符合NumPy的广播规则,该函数可能会抛出ValueError 参数:array 待修改的数组。shape 修改后的形状。subok 如果为True,则子类将被传递,否则返回的数组将被强制为基类数组(默认值)。 expand_dims() 原型:numpy.expand_dims(a, axis) 作用:通过在指定位置插入新的轴来扩展数组形状。 参数:a 输入数组;axis 忻州插入的值 squeeze() 原型:numpy.squeeze(arr, axis) 作用:从给定数组的形状中删除一维的条目。 参数:arr 输入的数组;axis 删除轴的位置 注意:不管是新增还是删除,shape元组元素值相乘的值都是固定的。如果你删除的轴导致shape元素相乘变了,那么就会报错。所以,删除或新增的轴只能是1。 concatenate()函数 原型:numpy.concatenate((a1, a2, ...), axis=0, out=None, dtype=None, casting="same_kind") 作用:用于沿指定轴链接相同形状的两个或多个数组 参数:(a1, a2, ...) 相同类型的数组,axis 沿着它链接数组的轴,默认为0。out输出到具体哪里。casting {'no', 'equiv', 'safe', 'same_kind', 'unsafe'} 控制如果类型发生转换的话怎么办 stack()函数 原型:numpy.stack(arrays, axis=0, out=None) 作用:用于沿新轴链接数组序列 参数:arrays 相同形状的数组序列。axis 数组中的轴,输入数组沿着它来堆叠。out 准备一个空间接收返回的结果。 hstack()函数 原型:numpy.hstack(tup) 作用:是numpy.stack函数的变体,它通过水平堆叠来生成数组 vstack()函数 原型:numpy.vstack(tup) 作用:是numpy.stack函数的变体,它通过垂直堆叠来生成数组 split()函数 原型:numpy.split(ary, indices_or_sections, axis=0) 作用:函数沿特定的轴将数组分割为子数组 变体:hsplit水平切分,vsplit垂直切分 参数: . ary 被分割的数组。 . indices_or_sections 是一个证书,就用该数平均切分没如果是一个数组,为沿轴切分的位置(左开右闭)。一般用简写形式更直观 . axis 沿着那个维度进行切向,默认为0,横向切分;为1时,纵向切分。 resize()函数 原型:numpy.resize(a, new_shape) 作用:返回指定大小的新数组。不足的会自动补足(从第0个元素开始循环补足)不会想reshape那样报错。 参数:a 数组,new_shape新的形状 append()函数 原型:numpy.append(arr, values, axis=None) 作用:在数组的末尾添加值。追加操作会分配整个数组,并把原来的数组复制到新的数组中(注意!!原来的数组并不会有变化),输入数组的维度必须匹配否则将生成ValueError 参数:arr 输入数组,values 要想arr添加的值,需要和arr形状相同(处理要添加的轴)axis 默认为None。当axis无定义时,是横向加成,返回总是一维数组!当axis有定义的时候,分别为0和1的时候。为0的时候(列数要相同)。当axis为1时,数组是加载右边(行数要相同) insert()函数 原型:numpy.insert(arr, obj, values, axis=None) 作用:在给定索引之前,沿给定轴在输入数组中插入值 注意:如果值的类型转换为要插入的类型,则它与输入数组不同。插入没有原地的,函数会返回一个新的数组。此外,如果未提供轴,则输入数组会被展开 参数:arr 输入数组。obj 在其之前插入值的索引。values 要插入的值。axis 沿着它超入的轴,如果未提供,则输入数组会被展开成一维 delete()函数 原型:numpy.delete(arr, obj, axis) 作用:返回从输入数组中删除指定子数组的新数组。与insert函数的情况一样,如果未停工轴参数,则返回的数组将是一维的。 参数:arr 输入数组。obj 可以被切片,整数或者整数数组,表名要从输入数组删除的子数组。axis 沿着它删除给定数组的轴,如果未提供,则输入数组会被展开。
x = numpy.arange(12).reshape(3,4) print(x) # 因为没有指定axis,所有会将x展开成一维后,删除下标[2,3,4]元素,并返回新数组。如果只需删除一个元素,可以直接删除下标就行 b = numpy.delete(x, [2,3,4]) c = numpy.delete(x, 1, axis=0) # 删除axis轴的下标为1的元素 print(c)
unique()函数 原型:unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None, *, equal_nan=True) 作用:去除数组中的重复元素 参数: 1.arr 输入数组,如果不是一维数组则会展开 2.return_index 如果为true,返回新列表元素在旧列表中的位置(下标),并以列表形式储存 3.return_inverse 如果为true,返回旧列表元素在新列表中的位置(下标),并以列表形式存储 4.return_counts 如果为true,返回去重数组中的元素在原数组中出现的次数
x = numpy.array([1,2,3,4,5,2,6,7,8,9,1,2,3,2,3,1,1,2]).reshape(3,6) # 直接返回去重后新的ndarray数组 a = numpy.unique(x) # 返回的是一个tuple,第一个元素是去重后的新数组,第二个是新数组每个元素在旧数组中的下标 b = numpy.unique(x,return_index=True) # 返回的是一个tuple,第一个元素是去重后的新数组,第二个是旧数组元素在新数组中的下标 c = numpy.unique(x,return_inverse=True) # 返回的是一个tuple,第一个元素是去重后的新数组,第二个是新数组元素,在旧数组中出现的次数 d = numpy.unique(x,return_counts=True) # 注意,这几个return_...参数是可以组合使用的,具体返回信息,试一下就知道了
十、字符串函数 简介:是用于对dtype.string_或numpy.unicode_的数组执行向量化字符串操作,基于Python内置库中的标准字符串函数在字符数组类(numpy.char)中定义 1.对两个数组的元素进行字符串连接 print(numpy.char.add(['sunck'],['good'])) print(numpy.char.add(['sunck','ch'],['good', 'nice'])) 2.返回按元素多重连接后的字符串 print(numpy.char.multiply('good',3)) 3.将字符串居中并使用指定字符串在左侧和右侧进行填充 print(numpy.char.center(['nice','good'],10,fillchar='*')) 4.将字符串第一个字母转换为大写 print(numpy.char.capitalize(['zhangsan is a good man', 'lisi is a good man'])) 5.将字符串的每一个单词的第一个字母转换为大写 print(numpy.char.title(['zhangsan is a good man', 'lisi is a good man'])) 6.数组元素转换为小写 print(numpy.char.lower(['zhangsan is a good man', 'lisi is a good man'])) 7.数组元素转换为大写 print(numpy.char.upper(['zhangsan is a good man', 'lisi is a good man'])) 8.指定分隔符对字符串进行分割,并返回数组列表 print(numpy.char.split(['zhangsan is a good man', 'lisi is a good man'], sep=' ')) 9.返回元素中的行列表,以换行符分割 print(numpy.char.splitlines(['zhangsan\n is\n a\n good\n man', 'lisi\n is\n a good man'])) 10.移除元素开头或者结尾处的特定字符 print(numpy.char.strip(['***nice***', '***good***'],'*')) 11.使用新字符串替换字符串中所有子字符串 print(numpy.char.replace(['zhangsan is a good man', 'lisi is a good man'], 'good', 'nice')) 12.编码,数组元素一次调用str.encode print(numpy.char.encode(['zhangsan is a good man', 'lisi is a good man'], 'utf-8')) 13.解码,数组元素一次调用str.decode print(numpy.char.decode([b'zhangsan is a good man' b'lisi is a good man'], 'utf-8'))
十一、数学函数 1.标准三角函数sin()、cos()、tan() 2.反三角函数arcsin()、arccos()、arctan()、degrees() 3.numpy.around()函数 原型:numpy.around(a, decimals=0) 作用:返回指定数字的四舍五入值 参数:a 数组。decimals 舍入的小数位位数。默认值为0.如果为负数,证书将四舍五入到小数点左侧的位置 4.numpy.floor(arr)函数。向下取整。 5.ceil(arr)函数。向上取整。
十二、算术函数 1.add()、subtract()、multiply()、divide()。就是+-*/ 2.reciprocal(arr) 返回参数组个元素的倒数(四分之一的倒数是四。0.25 * 4=1) 3.power(a1,a2) 将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂 4.mode(a1,a2) 计算输入数组中相应元素相除后的余数
十三、统计函数 1.amax(arr, axis=None,...)、amin(arr, axis=None,...) 作用:计算数组中的元素沿指定轴的最大值、最小值 2.percentile()函数 原型:numpy.percentile(a,p,axis) 作用:百分位数是统计中使用的度量,表示小于这个值的观察值的百分比 参数:a 输入数组。p 要计算的百分位数,在0~100之间。axis 沿着它计算百分位数的轴。 说明:第p个百分位数是一个这样的值,它使得至少有p%的数据项小于或等于这个值,且至少有(100-p)%的数据项大于或等于这个值。 举例说明:高等院校的入学考试成绩经常以百分位数的形式报告。比如,假设某个考生在入学考试中的语文部分的原始分数为54分。相对于参加同一考试的其他学生来说,他的成绩如何并不容易知道。但是如果原始分数为54恰好对应的是第70百分位数,我们就能知道大约70%的学生的考分比他低,而约30%的学生考分比他高。这里的p=70。 3.ptp()函数 原型:numpy.ptp(a, axis=None, out=None, keepdims=<no value>) 作用:求数组中最大值与最小值的差值。 参数:a 输入数组。axis 沿哪个轴去得到最大值与最小值的差值。 4.median()函数 原型:numpy.median(a, axis=None, out=None, overwrite_input=False, keepdims=False) 作用:返回数组中元素的算术平均值。如果提供了轴,则沿其计算 5.mean()函数 原型:numpy.mean(a, axis=None, dtype=None, out=None, keepdims=<no value>, *, where=<no value>) 作用:返回数组中元素的中位数。如果提供了轴,则沿其计算 6.average()函数 原型:numpy.average(a, axis=None, weights=None, returned=False, *, keepdims=<no value>) 作用:根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值,可以接受一个轴参数。如果没有指定,则数组会被展开。 加权平均值:将各数值乘以响应的权数,然后加总求和得到总体值,再除以总的单位数。考虑数组[1,2,3,4]和相应的权重[4,3,2,1],通过将相应元素的成绩相加,并将和除以权重的和,来计算加权平均值。加权平均值=(1*4 + 2*3 + 3*2 + 4*1)/(4+3+2+1) 参数:a 输入数组。axis 沿哪个轴。returned 同时返回权重和。 7.std()函数 原型:numpy.std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=<no value>, *, where=<no value>) 作用:求一组数的标准差。用来衡量一组数据的稳定性。 标准差:是一组数据平均值分散程度的一种度量。标准差是方差的算术平方根。 公式:std = sqrt(mean((x - x.mean())**2)) 说明:如果数组是[1,2,3,4],则器平均值为2.5。因此,差的平方是[2.25,0.25,0.25,2.25],并且其平均值的平方根除以4,即sqrt(5/4),结果为:1.1180339887498949 8.var()函数 原型:numpy.var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=<no value>, *, where=<no value>) 作用:求一组数的方差。用来衡量一组数据的稳定性。方差开根号就是标准差。 方差:统计中的方差(样本方差)是每个样本值与全体样本值的平均数,即mean((x-x.mean())**2)。换句话说,标准差是方差的平方根
十四、排序函数 种类 速度 最坏情况 工作空间 稳定性 'quicksort'(快速排序) 1 O(n^2) 0 否 'mergesort'(归并排序) 2 O(n*log(n)) ~n/2 是 'heapsort'(堆排序) 3 O(n*log(n)) 0 否 快速排序步骤:① 选定Pivot中心轴。② 将大于Pivot的数字放在Pivot的右边。③ 将小于Pivot的数字放在Pivot的左边。④ 分别对左右子序列重复前三步。 归并排序:① 将序列中带排序数组分为若干组,每个数字分为一组。② 将若干个组两两合并,保证合并后的组是有序的。③ 重复第二步操作知道值剩下一组,排序完成。 堆排序:① 将待排序的序列构造成一个最大堆,此时序列的最大值为根节点。② 依次将根节点与待排序序列的最后一个元素交换。③ 再维护从根节点到该元素的前一个节点为最大堆,如此往复,最终得到一个递增序列。 1.sort()函数 原型:numpy.sort(a, axis, kind, order) 功能:返回输入数组的排序副本 参数:a 要排序的数组。axis 沿这它排序数组的轴,如果没有数组会被展开,沿着最后的轴排序,axis=0 按列排序,axis=1 按行排序。kind 排序算法,默认为'quicksort'。order 如果数组包含字段,则是要排序的字段。 2.argsort()函数 原型:numpy.argsort(a, axis=-1, kind=None, order=None) 作用:对输入数组沿给定轴执行间接排序,并使用指定排序类型返回数据的索引数组。这个索引数组用于构造排序后的数组。 3.lexsort()函数 原型:numpy.lexsort(keys, axis=-1) 作用:使用键序列执行间接排序。键可以看做是电子表格中的一列。该函数返回一个索引数组,使用它可以获得排序数据。 注意:最后一个键恰好是sort的主键。 举例:小升初考试,重点班录取学生按照总成绩录取。在总成绩相同时,数据成绩高的优先录取,在总成绩和数学成绩相同时,按照英语成绩录取……这里,总成绩排在电子表格的最后一列,数学成绩在倒数第二列,英语成绩在倒数第三列。 4.msort()函数 原型:numpy.msort(a) 作用:数组按第一个轴排序,返回排序后的数组副本 说明:numpy.msort(a) 相等于 numpy.sort(a, axis=0) 5.sort_complex()函数 原型:sort_complex(a) 作用:对复数按照先实部后虚部的顺序进行排序 6.partition()函数 原型:partition(a, kth, axis=-1, kind='introselect', order=None) 作用:指定一个数,对数组进行分区
import numpy x = numpy.array([3,4,2,1]) # 将数组x中所有元素(包括重复元素)从小到大排列,3表示是,比3小的拍在该数字的前面,比该数字大的拍在该数字的后面。 print(numpy.parttion(x,3)) # 小于1的在前面,大于3的在后面,1和3之间的在中间 print(numpy.parttion(x,(1,3)))
7.argpartition()函数 原型:argpartition(a, kth, axis=-1, kind='introselect', order=None) 作用:可以通过关键字kind指定算法沿着指定轴对数组进行分区。返回的下标。和partition相似。kth这里指的是下标。
十五、搜索函数 1.max()、min()函数 作用:沿指定轴返回最大值和最小值 2.argmax()、argmin()函数 作用:沿给定轴返回最大和最小元素的索引 3.nonzero()函数 作用:返回输入数组中非0元素的索引 4.where()函数 原型:numpy.where(condition, [x, y], /) 作用:返回输入数组中满足给定条件的元素索引 例子:numpy.where(x>30, x) 5.extract()函数 原型:numpy.extract(condition, arr) 作用:根据某个条件重数组中抽取元素,返回满足条件的元素 例子:numpy.extract(numpy.mod(x,2), x)