一、什么是numpy
二、为什么要有numpy
python中没有数组,只有list。list相对于数组而言的缺点是,python作为一门动态语言,每一个元素的类型可以是不一样的,那么对于列表中的每一个元素python需要检查他的类型,当数据量较大时,解释速度会比数组更慢。
python的库中是有array的,可以用来生成’数’组。array.array(‘数据类型’, 列表 )。但是它没有将这些数据看作向量或者矩阵,没有为这些数据配备向量相关或矩阵相关的运算,所以在机器学习中使用并不方便。numpy正是因此出现的。
numpy中的元素必须是统一类型,优先级:字符串 >浮点型> 整形
三、numpy怎么用
基础使用
导入numpyimport numpy as np
查看版本print(numpy.__version__)
随便创建一个数组nparr = np.array(i for i in range(10)),nparr = np.array([1,2,3])
查看numpy产生数组的类型print(x.dtype) # datatype的缩写
创建0数组np.zeros(10) np.zeros((3,5)) # 三行5列
创建1数组并指定形状和类型np.ones(shape=(3,5), dtype=int) np.ones([3, 5])
创建单一数值数组np.full(shape=(3, 5), fill_value=6, dtype=int)
使用简单的方式创建数组nparr= np.arange(10,0.2)# 步长可以是浮点数
创建等差数列nparr = np.linspace(20,5) # 从0到20等步长切出五个数字
random
是numpy中就有的random
import numpynumpy.random.random((1000,20)) # 生成1000行,20列,范围在0-1之间的浮点数numpy.random.randint(0, 10, 10) # 前面俩是范围,第一个参数可以不写,后面是数量numpy.random.randint(0, 10, size = 10) # 形参关键字sizenumpy.random.randint(0, 10, size = (3, 5)) # 可以传元祖numpy.random.seed(666) # 随机种子,参数是数字,一样的种子被重复种下会长成一样的树,全局有效,即使用一次后下一次还会生效numpy.random.normal(0, 1,size=1000)# 生成正态分布数据,均值,方差,矩阵(元组),size= # 均值默认0,方差默认1
基本属性
nparr.nidm 查看几维数组
nparr.shape 返回元组,查看元素数量与维度
nparr.size 返回元素个数
numpy.array的数据访问
nparr[0][0] # 不建议,不可以切片多维数组(第五行),为了养成使用习惯统一使用下面的方式nparr[(0,0)] # 等同于下面nparr[0,0]# numpy可以使用切片nparr[3:8] #切一维数组3~8nparr[:2, :3] # 切前2行,前3列# 注意,numpy切片后修改元素时修改的是原矩阵的数值subx = nparr[:2, :3].copy() # 这样才能创建一个新的矩阵np.imread('路径') # 把图片读成数组
reshape
# 改变矩阵形状new_nparr = nparr.reshape() # 重置的不是原来的矩阵,所以要赋给新的值nparr.reshape(10, -1) # 把该向量或矩阵变成10行的矩阵,每列而有多少元素不管nparr.reshape(-1,10) # 把该向量或矩阵变成10列的矩阵,每行而有多少元素不管
合并操作
np.concatenate([x,y], axis=0) # []内可以有好几个矩阵,axis默认为0,合并行,1是合并列,也可以填更高的维度,只能拼接同维矩阵np.concatenate([x,y]) # 当x是一维,y是二维就不行了,需要转化成同维(reshape)np.vstack([放入矩阵]) # 可以智能竖直拼接,不用reshape verticalnp.hstack([放入矩阵]) # 可以智能横向拼接,不用reshape Horizontal
分割操作
nparr = np.arange(10)x1, x2, x3 = np.split(nparr, [3,7]) #out: x1 = 0,1,2x2 = 3,4,5,6x3 = 7,8,9a = np.arange(16).reshape([4, 4])a1, a2 = np.split(a, [2]) # 默认横着切,用axis参数可以调节out: a1 = [[0,1,2,3],[4,5,6,7]]a2 = [[8,9,10,11],[12,13,14,15]]a = np.vsplit() # 竖切,等价于split中axis等于0a = np.hsplit() # 横切,等价于split中axis等于1
Universal Functions
numpy类型的矩阵可以对本身与数字进行四则运算nparr + 1
np.sin(nparr)np.abs(nparr) # 绝对值np.cos(nparr)np.tan(nparr)np.around(3.14) # 四舍五入值np.ptp(nparr) # 极差np.exp(nparr) # 每一个元素的e次方np.power(3, nparr) # 3为底的np.log10()矩阵与另一个矩阵之间可以加减,但不能乘除,乘除结果是对应元素之间的乘除,而不是矩阵的乘除nparr1.dot(nparr2) # 矩阵1和矩阵2相乘,所有横乘竖的第一个相加成为第一个值nparr.T # 矩阵转置np.vstack([矩阵] * 2 ) # 整个矩阵复制后竖向拼接np.tile(nparr, (2,1)) # 堆叠,在行向量堆叠俩次,列向量堆叠一次
矩阵的逆
invA = np.linalg.inv(A)# 矩阵的逆和原矩阵相乘得出的单位矩阵对角线是都是1只有正方的矩阵才有逆,我们可以求伪逆矩阵pinvA = np.linalg.pinv(A)
聚合运算
np.sum(nparr,axis=参数) # 等价于nparr.sum()np.count_nonzero(nparr)np.min(nparr) # 等价于nparr.min()np.max(nparr) # 等价于nparr.max()np.prod(nparr) # 乘积np.mean(nparr)np.median(nparr)np.percenttile(nparr, q=50) # 求50%的百分位点np.var(nparr) # 求方差np.std(nparr) # 标准差
排序和使用索引
np.random.shuffle(nparr) # 打乱np.sort(nparr) # 排序,并返回一个新值nparr.sort() # 排序nparr本身# 当nparr是二维数组时np.sort(nparr, axis=0) # axis默认是1np.argsort(nparr) # 返回排序后元素在原数组的索引np.partition(nparr, 3) # 比3小的放左边,比3大的放右边np.argpartition(nparr, 3) # 返回数组,比三小的值的原索引在左边,右边相反
fancy indexing和比较运算
nparr = np.arange(16)ind_1 = [3, 5, 8]ind_2 = [[0, 2],[1, 3]]print(nparr[idx_1])print(nparr[idx_2])=========================out:arrray([3, 5, 8)array([[0, 2],[1, 3]])nparr1 = nparr.reshape(4, -1)row = np.array([0, 1, 2])clo = np.array([1, 2, 3])clo1 = [True, False, True, True]nparr1[clo, row]nparr1[0, col]nparr1[:2, col]nparr1[1:3, col1]out:array([1, 6, 11])array([1, 2, 3])array([[1, 2, 3],[5, 6, 7]])array([[4, 6, 8],[8, 10, 11]])比较:可以指定行或列nparr > 3 # 返回布尔类型数组np.sum(nparr > 3)np.count_nonzero(nparr <= 3)np.any(nparr >= 0) # 有一个等于零返回Truenp.all(nparr > 0) # 全等于0返回Truenp.count((nparr > 3) & (nparr < 10))& | ~ 与或非x[x[:,3] % 3 == 0, :] # 抽取能整除3的行p12到p21不知道有没有看过,先掠过了
arg运算
import numpy as npnp.argmin(参数) # 返回最小值的索引np.argmax(参数) # 返回最大值的索引
