一、numpy快速入门
1、什么是numpy:
numpy是python的一个矩阵类型,提供了大量矩阵处理的函数,非正式来说,就是一个使运算更容易,执行更迅速的库,因为它的内部运算是通过c语言而不是python实现的
2、numpy包含两种基本数据:
数组:就是有序的元素序列,把具有相同类型的若干元素按无序的形式组织起来的一种形式
矩阵:在数学中,矩阵就是一个按照长方阵列排列的复数或实数集合
数组与矩阵的区别:
两者都可以用于处理行列表示的数字元素,但是在这两个数据类型上执行相同的数学运算可能得到不同的结果,其中numpy函数库中的matrix与MATLAB中matrices等价
下面是一些简单使用方法:
1 import numpy 2 3 #看上去没有区别 4 n1=numpy.array(['aa','bb','cc','dd','ee']) 5 list1=['aa','bb','cc','dd','ee'] 6 print(n1[0]) 7 print(list1[0]) 8 9 print(n1[1:3]) 10 print(list1[1:3]) 11 12 for i in n1: 13 print(i) 14 15 for i in list1: 16 print(i)
1 #ndarray和python list不同之处 2 #ndarray里面的元素必须是同一种类型 3 n1=numpy.array(['aa','bb','cc','dd','ee',100]) 4 print(type(n1[-1])) 5 print(n1[-1]) 6 7 #矢量运算 8 #相加 9 a1=numpy.array([1,2,3]) 10 a2=numpy.array([2,3,4]) 11 print(a1+a2)#>>:[3,5,7] 12 13 #相乘 14 a1=numpy.array([1,2,3]) 15 print(a1*3)#>>:[3,6,9] 16 17 #比如乘方 18 #先产生3*3的矩阵,每个数字都是0-9之间 19 a1=numpy.random.randint(0,10,(3,3)) 20 print(a1)#随机产生>>:[[7 2 6][4 5 5][0 5 0]] 21 22 a2=a1**2 23 print(a2)#>>:[[49 4 36][16 25 25][ 0 25 0]]
1 #题目一: 2 a=numpy.array([1,2,3,4,5]) 3 b=a 4 a+=numpy.array([1,1,1,1,1]) 5 print(b)#>>:[2 3 4 5 6] 6 print(id(a),id(b)) 7 8 #题目二; 9 a=numpy.array([1,2,3,4,5]) 10 b=a 11 a=a+numpy.array([1,1,1,1,1]) 12 print(b)#>>:[1 2 3 4 5] 13 print(id(a),id(b)) 14 #由于a=a+[]是被从新定义了新的内存地址
1 j=numpy.array([[1,2,3],[1,1,1]]) 2 #普通列表方式访问 3 print(j[0]) 4 print(j[0][1]) 5 #矩阵的方式访问 6 print(j[0,1])
1 s=mat([1,2,3]) 2 print(s) 3 #矩阵类型 4 print(type(s)) 5 #访问矩阵中的第一元素 6 print(s[0,0]) 7 8 #把普通列表转成矩阵类型 9 lis=[111,234,534] 10 m=mat(lis) 11 print(type(m)) 12 #矩阵类型与矩阵类型相乘会报错 13 #矩阵数据类型的运算会强制执行数学中的矩阵运算,1*3的矩阵是不能与1*3的矩阵相乘的 14 #需要左矩阵的列数和右矩阵的行数必须相等才能相乘 15 #这是需要将其中一个矩阵转置,使得可以3*1的矩阵乘以1*3的矩阵,或是1*3的矩阵乘以3*1的矩阵 16 # print(s*m) 17 #numpy数据类型中有一个转置方法,能方便的进行矩阵乘法运算 18 print(s*m.T) 19 20 #查看数组和矩阵的维数 21 print(shape(m)) 22 23 #矩阵中每个元素的相乘法需要multiply方法 24 print(multiply(s,m))
1 #数组,矩阵的排序,默认快速排序方法 2 m=mat([3,2,5,8,4]) 3 m.sort() 4 print(m) 5 6 #得到矩阵中每个元素的排序序号 7 m=mat([3,2,5,8,4]) 8 res=m.argsort() 9 print(res)#[[1 0 4 2 3]] 10 11 #计算矩阵的均值 12 res=m.mean() 13 print(res)
1 j=mat([[1,2,3],[8,8,8]]) 2 #查看维数组,这是一个2*3的矩阵 3 print(shape(j)) 4 #取出第一行元素 5 print(j[1,:]) 6 #取出第0行,第0列的元素 7 print(j[0,0])
1 numpy.tile(A,reps)#将A重复reps次的输出 2 3 tile共有2个参数,A指待输入数组,reps则决定A重复的次数。整个函数用于重复数组A来构建新的数组。 4 5 函数格式tile(A,reps) 6 7 A和reps都是array_like 8 9 A的类型众多,几乎所有类型都可以:array, list, tuple, dict, matrix以及基本数据类型int, string, float以及bool类型。 10 11 reps的类型也很多,可以是tuple,list, dict, array, int, bool.但不可以是float, string, matrix类型。 12 13 假设reps的维度为d,那么新数组的维度为max(d,A.ndim)。下面分三种情况进行讨论: 14 15 (1)A.dim < d 16 17 则向A中添加新轴扩充A的维度。维度大小可以从shape中看出,一般通过向shape对应的元组中添加1完成对A维度的扩充。扩充完成后,则可根据reps的值对A中相应维度的值进行重复。 18 19 例如,一维数组shape为(3,),扩充至2维则shape值为(1,3),扩充至3维则shape值为(1,1,3) 20 21 (2)A.dim > d 22 23 将reps扩充至与A相同的维度。扩充方法同上,也是向shape对应元组中添1,然后再进行重复。 24 25 例如,4维数组A的shape为(2,3,4,5),而reps为(2,2)只有2维,那么就要对reps添维进行扩充,得到(1,1,2,2) 26 27 (3)A.dim = d 28 29 不需要扩充,直接按reps的值对相应维度的值进行重复
1 #结果相同 2 #一维重复输出 3 print(tile((1,2,3),3)) 4 print(array([1,2,3,1,2,3,1,2,3])) 5 6 #结果相同 7 b=[1,3,5] 8 print(tile(b,[2,3])) 9 print(array([[1,3,5,1,3,5,1,3,5],[1,3,5,1,3,5,1,3,5]])) 10 11 #二位重复输出 12 a=[[1,2,3],[5,4]] 13 print(tile(a,[2,3])) 14 print([[[1,2,3],[5,4],[1,2,3],[5,4],[1,2,3],[5,4]], 15 [[1,2,3],[5,4],[1,2,3],[5,4],[1,2,3],[5,4]]])
二、数组基础
numpy围绕这些称为数组的事物展开,实际上它被称为ndarrys,你不知道没事儿,使用numpy提供的这些数组,我们就可以以闪电般的速度执行各种有用的操作,如矢量和矩阵,线性代数等数学运算
numpy的主要对象是同种元素的多维数组,这是一个所有的元素都是一种的类型,通过一个整数元组索引的元素表格,在numpy中维度dimensions叫做轴axes,轴的个数叫做轶(rank)
例如:在3d空间一个点的坐标[1,2,3]是一个轶为1的数组,因为它只有一个轴,那个轴的长度为3
又例如:在以下例子中,数组的轶为2(它有两个维度)第一维度长度为2,第二维度长度为3
[[1,0,0],[0,1,2]]
numpy的数组类称作ndarray,通常被称作数组
1.ndarray.ndim
数组轴的个数,在python的世界中,轴的个数被称作轶
2.ndarray.shape
数组的维度,这是一个指示数组在每个维度上大小的整数元组,例如一个n排m列的矩阵,它的shape属性将是(2,3),这个元组的长度显然是轶,即维度或者ndim属性
3.ndarray.size
数组元素的总个数,等于shape属性中元组元素的乘积
4.ndarray.dtype
一个用来描述数组中元素类型的对象,可以通过创造或指定dtype使用标准python类型,另外numpy提供它自己的数据类型
5.adarray.itemsize
数组中每个元素的字节大小,例如,一个元素类型为float64的数组itemsize属性值为8(=64/8),又如,一个元素类型为complex32的数组item属性为4(=32/8)
6.ndarray.data
包含实际数组元素的缓冲区,通常我们不需要使用这个属性,因为我们总是通过索引来使用数组中的元素
三、数组的详细操作
from numpy import * a=array([0,1,2,3,4]) b=array([0,1,2,3,4]) c=arange(5) d=linspace(0,2*pi,5) print(a)#[0 1 2 3 4] print(b)#[0 1 2 3 4] print(c)#[0 1 2 3 4] print(d)#[0. 1.57079633 3.14159265 4.71238898 6.28318531] arr1=array([ [ [1,2,3,4,5], [2,3,4,5,6], [4,5,6,7,7], [3,4,5,6,8] ], [ [1,8,6,7,7], [1,6,6,7,10], [1,2,5,7,32], [1,4,6,2,33] ] ]) # print(arr1.shape) #array函数:接收一个普通的python序列,转成ndarray res=array([1,2,3,4,5,6,7,8]) print(type(res)) #zeros函数:创建指定长度或形状的全零数组 print(zeros((3,4))) #ones函数:创建指定长度或形状的全1数组 print(ones((3,3,3))) #empty函数:创建一个没有任何具体指的数组(准备的说是一些未初始化的垃圾值) print(empty((5,5))) #nan代表空值,或缺失值 #arrange函数:类似于python的range函数,通过指定开始值,结束值和步长 #来创建一维数组,注意:数组不包括结束值,顾头不顾尾 print(arange(2,30,3)) #linspace函数:通过指定开始值,结束值和元素个数创建一维数组, # 可以通过endpoint关键字指定是否包括结束值,缺省设置是包括结束值 #第一个参数是起始数,第二个参数是结束数,第三个参数是元素的个数 #生成的是等差数列 print(linspace(1,20,3)) #logspace函数:和linspace类似,不过它创建等比数列 #生成的是等比数列 #第一个数是代表10的2次方,第二个数是代表10的20次方,第三个是元素个数 print(logspace(2,20,3)) #使用随机数填充数组,即使用numpy.random模块和random()函数,数组所包含 #的元素数量由参数决定 res=random.random((2,3,4)) print(res) # #-1会自动计算 # res=arange(2,20,2) # print(res) # res=arange(2,20,2).reshape((3,-1)) # print(res) #总结: # 1.先规范显示出数组 # 2.层层去中括号,值到2无中括号,每去一层,一个维度,去掉一层[],后的元素个数(逗号隔开)即该维度的元素个数 #创建numpy数组可以通过dtype属性显示指定数据类型,如果不指定, # numpy会自己推断出合适的数据类型,所以一般无需显示指定 # astype方法,可以转换数组的元素数据类型,得到一个新数组 arr2=array([1,2,3,4]) print(arr2) print(arr2.dtype) #改变arr2的数据类型,重新赋值给arr2 arr2=arr2.astype('float') print(arr2) print(arr2.dtype) #使用unicode编码,每个元素长度为2,U为大写 arr3=arr2.astype('|U2') print(arr3) print(arr3.dtype) #使用string进行编码(转换为十六进制编码),每个元素长度为2,S为大写 arr4=arr2.astype('|S2') print(arr4) print(arr4.dtype) #自动转换数据类型 arr5=array([1,2,3,'4'],dtype=float) print(arr5) print(arr5.dtype) #改变数组的形状 #1.reshape不会改变原来的数组元素个数,但会得到新的ndarry视图 arr6=arange(20) print(arr6) arr6=arr6.reshape((4,5)) print(arr6) #拷贝,生成一个副本,修改副本不会影响原数组 arr=arange(20) print(arr) arr_copy=arr.copy() arr_copy[0]=88 print(arr_copy) print(arr) print('========================') #视图会改变原数组的值,视图的变量名都指向同一个内存地址空间 arr=arange(20) print(arr) arr2=arr.reshape((4,-1)) arr2[0][1]=88 print(arr2) print(arr) #数值型dtype的命名方式: # 一个类型名(比如int,float),后面接着一个用于表示各元素位长度的数字 # 比如:表中的双精度浮点值,即python中的float对象,需要占用8个字节(即64位) # 因此该类型在numpy中就记为float64 # 每种类型有一个相对应的类型代码,即简写方式,参照下面的表 #numpy基本操作 # 算术运算 # 数组不用循环即可对每个元素执行批量运算,这通常就叫做矢量化,即用数组表达式代替循环的做法 # 矢量化数组运算性能要比纯python方式快上一两个数量级 # 大小相等的数组之间的任何运算都会将运算应用到元素级 # 加法: arr=arange(0,20,2) print(arr) arr1=arr+2 print(arr1) print(arr+arr1) print(arr*2) #会显示不能被0除错误信息 # print(arr1/arr) arr1=random.random((2,3)) arr2=random.random((3,2)) print(arr1,arr2) #数组形状不同不能相加 # print(arr1+arr2) #转换相同形状后计算 print(arr1+arr2.reshape((2,3))) #元素级的运算 # 加,减,乘,除,幂运算等,可以用于数组与标量,大小相等数组之间 # 在numpy中,大小相等的数组之间运算,为元素级运算,即只用于位置相同的元素之间 # 所得到的运算结果组成一个新的数组,运算结果的位置跟操作数位置相同 print('=============================') # 两个二维矩阵(多维数组即矩阵)满足第一个矩阵的列数与第二个矩阵的行数相同 # 那么可以进行矩阵乘法,即矩阵积,矩阵积不是元素级的运算 # 两个矩阵相乘结果所得到的数组中每个元素为, # 第一个矩阵中与该元素行号相同的元素与第二个矩阵中与该元素列号相同的元素,两两相乘后求和 #矩阵积 arr1=random.random((2,3)) arr2=random.random((3,2)) print(arr1.shape,arr2.shape) print(arr1) print(arr2) print('------------------') print(arr1.dot(arr2)) # (2, 3) (3, 2) # [[0.34504786 0.05553567 0.12492583] # [0.63312505 0.20942331 0.14286747]] # [[0.90689695 0.61868066] # [0.71365305 0.91594229] # [0.38928685 0.54340045]] # ------------------ # 计算方式:0.34504786*0.90689695+0.05553567*0.71365305+0.12492583*0.38928685=0.40118803 # [[0.40118803 0.33222666] # [0.77925118 0.66115613]] #在矩阵中,竖着的叫行轴axis[0],横着的叫列轴axis[1] #矩阵积在生活中的应用 # 产品A 产品B 产品C # 公司1 89 95 83 # 公司2 79 75 77 # 公司3 74 51 88 # 单价 体积 # 产品A 10 1 # 产品B 6 10 # 产品C 9 1 # 算出,公司1,公司2,公司3,各自的总产品总金额和总体积 arr1=array([ [89,95,83],[79,75,77],[74,51,88] ]) arr2=array([ [10,1],[6,10],[9,1] ]) print(arr1.dot(arr2)) # 产品 体积 # 公司1 [2207 1122] # 公司2 [1933 906] # 公司3 [1838 672] #多维数组的索引 arr3=random.random((2,3,4)) print(arr3) print(arr3[0,1:3,0:3]) #0表示第一组,1:3表示第一组中的第2行,第3行,[0:2]表示取第0个,和第2个索引位置,[0,2]加中括号表示选择,不是范围 # [ # [ # [0.76639132 0.59079559 0.23644078 0.00451106] # [0.45136272 0.24304024 0.83266546 0.04835091] # [0.73851614 0.44415277 0.1467127 0.19508756] # ] # # [ # [0.96947774 0.95681595 0.8278818 0.71830521] # [0.35352713 0.92370433 0.78588604 0.12943099] # [0.58588268 0.70987566 0.85868567 0.85980889] # ] # ] # # # [[0.45136272 0.73851614] # [0.83266546 0.1467127 ]] #花式索引 arr1=arange(32).reshape((4,8)) print(arr1) # [[ 0 1 2 3 4 5 6 7] # [ 8 9 10 11 12 13 14 15] # [16 17 18 19 20 21 22 23] # [24 25 26 27 28 29 30 31]] # [[ 8 9 10 11 12 13 14 15] print(arr1[[1,2,3]]) # [[ 8 9 10 11 12 13 14 15] # [16 17 18 19 20 21 22 23] # [24 25 26 27 28 29 30 31]] print(arr1[[0,1,2],[0,1,2]]) # [ 0 9 18] print(arr1[[1,2],1:3]) # [[ 9 10] # [17 18]] # ix_函数产生一个索引器 print(ix_([0,2],[1,3])) # (array([[0],#0表示取第一行 # [2]]),#2表示取第三行 array([[1, 3]]))#表示取第一行的第2个,第三行的第4个 print(arr1[[0,2],[1,3]]) #布尔索引 names=array(['maple','ffm','jerry',nan ]) names[names=='maple']='angel' print(names) names[names=='nan']='marry' print(nan) print(names) # 数组转置与轴对换 # transpose函数用于数组转置,对于二维 数组来说就是行列互换 # 数组的T属性,也是转置 arr1=arange(32).reshape((4,8)) print(arr1) # 横轴与纵轴的转变,修改时视图 arr2=arr1.T print(arr2) # 横轴与纵轴的转变,修改时视图 arr3=arr1.transpose() print(arr3) # 通用函数:快速的元素级数组函数 # ufunc:一种对ndarray中的数据执行元素级运算的函数,也可以看做是简单函数 # (接受一个或多个标量值,并产生一个或多个标量值)的矢量化包装器 arr=random.random((2,3,4)) res=abs(arr) print(res) print(sqrt(res)) arr=arange(10).reshape((2,-1)) arr2=arange(10).reshape((2,-1)) # x的y次方 print(power(arr,arr2)) # 判断是否为空值,如果为空就是True,不为空就是False arr3=array([ [nan,1,2,3], [1,2,3,4] ]) print(isnan(arr3)) # 聚合函数 # 聚合函数是对一组值(比如一个数组)进行操作,返回一个单一值作为结果的函数, # 因此求数组所有元素之和,求所有元素的最大最小值以及标准差的函数就是聚合函数 arr=array([1,2,3,4]) print(arr.max()) print(arr.min()) print(arr.mean()) print(arr.std()) print(sqrt(power(arr-arr.mean(),2).sum()/arr.size)) # 聚合函数可以指定对数值的某个轴元素进行操作 arr=array([ [1,2,3,4], [3,4,5,6] ]) # 对同一列上的元素进行聚合 print(arr.mean(axis=0)) # 对同一行上的元素进行聚合 print(arr.mean(axis=1)) print(arr.sum(axis=0)) print(arr.max(axis=1)) print(arr.std(axis=0)) # where arr1=array([1.1,2.2,3.3,4.4]) arr2=array([1.2,2.3,3.4,4.5]) arr_bool=array([True,False,False,True]) # 数组合并成一个zip对象 res=zip(arr1,arr2,arr_bool) print(res) result=[x if bl else y for x,y,bl in res] print(result) result=[(x if bl else y )for x,y,bl in res if x>2 ] print(result) # where(表达式数组,当前表达式为True提取的数组,当前表达式为False提取的数组) print(where(arr_bool,arr1,arr2)) # unique去重功能 arr=array(['中国','美国','英国','印度','毛里求斯','梵蒂冈','梵蒂冈','中国','美国']) print(arr) arr2=unique(arr) print(arr2) # 数组的存取 # 存数组 arr=random.random((2,3,4)) # 保存为二进制格式 save('data',arr) # 读取数据需要文件后缀 arr1=load('data.npy') print(arr1) # 存取文本文件.可以自定义文件(array.txt) # 读取数据操作 # faname 文件名 # dtype 数据类型 # comments 注释行的符号定义 # converters 转换函数 # skiprows 跳过行数 # usecols 使用哪些列 arr=loadtxt('array.txt',delimiter=',') print(arr) res=genfromtxt('array.txt',delimiter=',') print(res) from io import StringIO c=StringIO('0 1 2 3') print(c) print(loadtxt(c)) savetxt('array1.txt',arr,delimiter=',',fmt='%d')#fmt='%.2f'保留2位小数 savetxt('array2.txt',arr.reshape((4,3)),delimiter=',',fmt='%d')