有些萌新还在使用Pycharm进行Numpy等的学习,个人建议不要偷懒,下载anaconda,使用Jupyter Notebook进行探索性学习。不明白他们之间关系的可以看以下文章。
https://blog.csdn.net/suic009/article/details/122803865?spm=1001.2014.3001.5502
当我们在Jupyter Notebook中执行import numpy未发生报错时,说明下载成功。
不成功的记得在编译器中pip install numpy 或者conda install numpy,注意环境变量和下载位置。
当然也可以查看其版本:
(小白ps:as的作用是给其起个别名;__version__,这样形式的一般都是使用的这个类或者对象内部的一些属性方法如__name__、__sizeof__()等。)
Jupyter提词器下载:
提前退出anaconda,打开anaconda prompt输入以下命令:
pip install jupyter_contrib_nbextensions -i https://pypi.mirrors.ustc.edu.cn/simple
jupyter contrib nbextension install --userpip install --user jupyter_nbextensions_configurator
jupyter nbextensions_configurator enable --user
再次进入jupyter notebook多了以下选项,点击进入
取消勾选,选中Hinterland
成功
一、Numpy与Python用于数组计算的性能对比首先我们以一个需求进行分析:
数组A是1~N数字的平方数组B是1~N数字的立方实现两个数组的加法
对比使用Numpy和原生Python的性能对比
对于Python:
def python_sum(n): """ Python实现数组的加法 @param n:数组的长度 """ a = [i**2 for i in range(n)] # 生成第一个数组 b = [i**3 for i in range(n)] # 生成第二个数组 c = [] for i in range(n): c.append(a[i] + b[i]) return c
对于使用Numpy:
def numpy_sum(n): """ numpy实现数组的加法 @param n:数组的长度 """ a = np.arange(n) ** 2 # 0 - n-1 每个数平方 b = np.arange(n) ** 3 return a+b # 结果元素与上方python相同。
我们分别对python_sum和numpy_sum传入1K,1W,10W、100W、1000W次对比运行时间:
%timeit python_sum(n)
%timeit numpy_sum(n)
将结果打包在一起,得到如下(记得统一时间单位,这里统一微秒。):
pytime = [432,4.69*1000,51.9*1000,533*1000,5.42*1000*1000]nptime = [5.63,31.1,282,5.16*1000,52.3*1000]
我们引用后面学到的Pandas将其转变为Dataframe形式的二维表格:
此时我们得到df。使用后面学到的matplotlib进行画图:
或
至于其为什么这么高效,除了内部的一些优化操作更加便捷以外,其数据类型更接近C语言。如Python中一个int类型占28个字节(24个来自于int封装对象,4个字节来自真正的int),而在numpy中一个int类型默认只占4字节。
anaconda中还有很多强大的功能,这些都离不开C语言,我们可以看到在ananconda的安装目录有存有MinGW文件。
二、Numpy的核心arrayarray对象的背景:
Numpy的核心数据结构,就叫做array就是数组,array对象可以是一维数组,也可以是多维数组;Python的List也可以实现相同的功能,但是array比List的优点在于性能好、包含数组元数据信息、大量的便捷函数;Numpy成为Scipy、Pandas、Scikit-Learn、Tensorflow、PaddlePaddle等框架的“通用底层语言”Numpy的array和Python的List的一个区别,是它元素必须都是同一种数据类型,比如都是数字int类型,这也是Numpy高性能的一个原因;
array本身的属性
shape:返回一个元组,表示array的维度ndim:一个数字,表示array的维度的数目size:一个数字,表示array中所有数据元素的数目dtype:array中元素的数据类型
创建array的方法
从Python的列表List和嵌套列表创建array使用预定函数arange、ones/ones_like、zeros/zeros_like、empty/empty_like、full/full_like、eye等函数创建生成随机数的np.random模块构建
array本身支持的大量操作和函数
直接逐元素的加减乘除等算数操作更好用的面向多维的数组索引求sum/mean等聚合函数线性代数函数,比如求解逆矩阵、求解方程组 2.1 使用list创建一维array和二维array
2.2 数组array的属性Array.shape 查看数组的形状
Array.ndim 查看数组的维度
Array.size 查看数组中元素的个数
Array.dtype 查看数组中元素的类型
Array.itemsize 查看单个元素所占字节数
Array.nbytes 查看数组中所有元素所占字节数
再次提醒,为保证高效率的计算,数组中的元素会统一类型。
如arr = [1,2.0,'3'] 元素类型会全部转变为object字符类型。没有object的话其次才是浮点型。
2.3 常用的array生成函数以下除了arrange和random,基本都是xx:生成xx类型数组;xx_like(a)模仿数组a生成xx类型数组。
使用arange创建数字序列
arange([start,] stop[, step,], dtype=None)
使用ones创建全是1的数组
np.ones(shape, dtype=None, order='C')
shape : int or tuple of ints
Shape of the new array, e.g., ``(2, 3)`` or ``2``.
使用ones_like创建形状相同的数组
ones_like(a, dtype=float, order='C')
使用zeros创建全是0的数组
np.zeros(shape, dtype=None, order='C')
使用zeros_like创建形状相同的数组
np.zeros_like(a, dtype=None)
使用empty创建全是0的数组
empty(shape, dtype=float, order='C')
注意:数据是未初始化的,里面的值可能是随机值不要用
使用empty_like创建形状相同的数组
empty_like(prototype, dtype=None)
使用full创建指定值的数组
np.full(shape, fill_value, dtype=None, order='C')
使用full_like创建形状相同的数组
np.full_like(a, fill_value, dtype=None)
使用random模块生成随机数的数组
randn(d0, d1, ..., dn) 随机数会在后面讲解
2.4 array本身支持大量操作和函数这里先稍做展示,后面会经常用到。
比如这样生成一个二维数组:
运算:
三、给数组排序Numpy给数组排序的三个方法:
numpy.sort:返回排序后数组的拷贝,即不改变本身。array.sort:原地排序数组而不是返回拷贝,即改变本身。numpy.argsort:间接排序,返回的是排序后的数字索引
3个方法都支持一个参数kind,可以是以下一个值:
quicksort:快速排序,平均O(nlogn),不稳定情况mergesort:归并排序,平均O(nlogn),稳定排序heapsort:堆排序,平均O(nlogn),不稳定排序stable:稳定排序3.1 np.sort排序 3.2 array.sort排序
即np.sort不改变操作的数组返回一个新数组,array.sort改变操作的数组。
个人喜欢用np.sort(),就算需要改变数组本身时,直接以arr = np.sort(arr)这种形式写就行了,要会灵活运用。
3.3 np.argsort 返回的是有序数字的索引 3.4 Python原生sorted与np.sort对比首先我们都知道python的列表里有一个.sort方法,这个方法是list独有的且也只能操作list。对于list.sort()它没有返回值改变list本身,要求内部类型统一否则会报错。
对于sorted(list)它的局限反而没那么大,还可以对字典等根据某个键、值进行排序。
但这些排序的内部都是基于冒泡排序完成的。而我们的np.sort则是快速排序。
由于快速排序具有很强的不稳定性, 所以也有上面说的这些可选:
四、Numpy常用random函数常用如下:
更多请查看官方网址:https://docs.scipy.org/doc/numpy-1.14.0/reference/routines.random.html
1、rand(d0, d1, ..., dn)
返回数据在[0, 1)之间,具有均匀分布
2、randn(d0, d1, ..., dn)
返回数据具有标准正态分布(均值0,方差1)
3、randint(low[, high, size, dtype])
生成随机整数,包含low,不包含high
如果high不指定,则从[0, low)中生成数字
(ps:在python中random.randint(a,b) 是包含b的)
4、random([size])
生成[0.0, 1.0)的随机数
5、choice(a[, size, replace, p])
a是一维数组,从它里面生成随机结果
6、shuffle(x)
把一个数组x进行随机排列
7、permutation(x)
把一个数组x进行随机排列,或者数字的全排列
8、normal([loc, scale, size])
按照平均值loc和方差scale生成高斯分布的数字
9、uniform([low, high, size])
在[low, high)之间生成均匀分布的数字
实例:对数组加入随机噪声
五、Numpy对数组按索引查询三种索引方法:
基础索引神奇索引布尔索引5.1 基础索引
对于一维数组,和list一样,这里略。
对于二维数组,我们用行坐标和列坐标进行定位:
X[行,列] 其中行列可以是数字坐标,也可以是类似切片类型的数据。列可以不写,此时只对行操作。
与列相关:
我们可以取切片进行多个数据的修改:
5.2 神奇索引我们前面用数字当索引,其实也可以用数组。
数字索引返回单个数据,数字切片索引返回从哪到哪的数据。而神奇索引返回数组对应下几个的值。
实例:获取数组中最大的前N个数字
对于二维数组,原理相同:
5.3 布尔索引根据True或False返回对应的数据。
对于二维:
还可以使用一些条件组合:
六、Numpy中的数学统计函数1、Numpy有哪些数学函数:
2、怎样实现按不同的axis计算
以上函数,都有一个参数叫做axis用于指定计算轴为行还是列,如果不指定,那么会计算所有元素的结果
3、实例:机器学习将数据进行标准化
A = (A - mean(A, axis=0)) / std(A, axis=0)
6.1 Numpy中的数学统计函数 6.2 Numpy的axis参数用途 6.3 机器学习将数据标准化七、Numpy计算数组中满足条件的个数
需求:有一个非常大的数组比如1亿个数字,求出里面数字小于5000的数字数目
1、使用numpy的random模块生成1亿个数字
2、使用Python原生语法实现
3、使用Numpy向量化操作实现
4、时间对比
八、给数组增加维度的三种方法 背景:
很多数据计算都是二维或三维的,对于一维的数据输入为了形状匹配,经常需升维变成二维
需要:
在不改变数据的情况下,添加数组维度;(注意观察这个例子,维度变了,但数据不变)
原始数组:一维数组arr=[1,2,3,4],其shape是(4, ),取值分别为arr[0],arr[1],arr[2],arr[3]
变形数组:二维数组arr[[1,2,3,4]],其shape实(1,4), 取值分别为a[0,0],a[0,1],a[0,2],a[0,3]
实操:
经常需要在纸上手绘数组的形状,来查看不同数组是否形状匹配,是否需要升维降维
3种方法:
np.newaxis:关键字,使用索引的语法给数组添加维度np.expand_dims(arr, axis):方法,和np.newaxis实现一样的功能,给arr在axis位置添加维度np.reshape(a, newshape):方法,给一个维度设置为1完成升维
方法1:np.newaxis关键字
方法2 :np.expand_dims方法
方法3:np.reshape方法
九、Numpy实现K折交叉验证的数据划分背景:K折交叉验证
为什么需要这个?
在机器学习中,因为如下原因,使用K折交叉验证能更好评估模型效果:
1、样本量不充足,划分了训练集和测试集后,训练数据更少;
2、训练集和测试集的不同划分,可能会导致不同的模型性能结果;
K折验证是什么
K折验证(K-fold validtion)将数据划分为大小相同的K个分区。
对每个分区i,在剩余的K-1个分区上训练模型,然后在分区i上评估模型。
最终分数等于K个分数的平均值,使用平均值来消除训练集和测试集的划分影响;
1、模拟构造样本集合
2、使用Numpy实现K次划分
结果如下:
十、Numpy数组合并操作背景:在给机器学习准备数据的过程中,经常需要进行不同来源的数据合并的操作。
两类场景:
1、给已有的数据添加多行,比如增添一些样本数据进去;
2、给已有的数据添加多列,比如增添一些特征进去;
以下操作均可以实现数组合并:
np.concatenate(array_list, axis=0/1):沿着指定axis进行数组的合并np.vstack或者np.row_stack(array_list):垂直vertically、按行row wise进行数据合并np.hstack或者np.column_stack(array_list):水平horizontally、按列column wise进行数据合并
1、添加多行
2、添加多列
十一、数组的乘法按照两个相乘数组A和B的维度不同,分为以下乘法:
数字与一维/二维数组相乘;一维数组与一维数组相乘;二维数组与一维数组相乘;二维数组与二维数组相乘;numpy有以下乘法函数:
*符号或者np.multiply:逐元素乘法,对应位置的元素相乘,要求shape相同@符号或者np.matmul:矩阵乘法,形状要求满足(n,k),(k,m)->(n,m)np.dot:点积乘法 解释:点积,也叫内积,也叫数量积
两个向量a = [a1, a2,…, an]和b = [b1, b2,…, bn]的点积定义为:
a·b=a1b1+a2b2+……+anbn。
1. 数字与数组相乘
2、一维数组与一维数组相乘
3 、二维数组和一维数组相乘
4、二维数组与二维数组相乘
十二、Numpy中广播的概念 广播:
简单理解为用于不同大小数组的二元通用函数(加、减、乘等)的一组规则
广播的规则:
1、如果两个数组的维度数dim不相同,那么小维度数组的形状将会在左边补1
2、如果shape的维度不匹配,但是有维度是1,那么可以扩展维度是1的维度匹配另一个数组;
3、如果shape的维度不匹配,但是没有任何一个维度是1,则匹配失败引发错误;
1、二维数组加一维数组
2 .两个数组均需要广播
3、不匹配的例子
十三、Numpy求解线性方程组对于Ax=b,已知A和b,怎么算出x?
求解:
验证:
十四、Numpy实现SVD矩阵分解从分量还原矩阵
十五、Numpy实现多项式曲线拟合 问题定义:
对于一堆数据点(x, y),能否只根据这些数据,找出一个函数,使得函数画出来的曲线和原始数据曲线尽量匹配?
多项式拟合问题:
任何可微连续的函数,都可以用一个N次多项式来估计,而比N次幂更高阶的部分为无穷小可以忽略不计
3次多项式即:a$x^3$ + b$x^2$ + cx + d
比如我们可以让sin(x) 约等于 a$x^3$ + b$x^2$ + cx + d
1、构造原始数据
2、使用Numpy拟合
十六、使用Matplotlib实现可视化绘图可以直接将Numpy的数组传给Matplotlib实现可视化绘图:
曲线图饼图柱状图直方图
1、绘制正弦曲线
2、绘制饼图
3、柱状图
4、直方图
十七、Numpy实现逆矩阵求解线性方程组对于这样的线性方程组:
x + y + z = 62y + 5z = -42x + 5y - z = 27
可以表示成矩阵的形式:
用公式可以表示为:Ax=b,其中A是矩阵,x和b都是列向量
逆矩阵(inverse matrix)的定义:
设A是数域上的一个n阶矩阵,若存在另一个n阶矩阵B,使得: AB=BA=E ,则我们称B是A的逆矩阵,而A则被称为可逆矩阵。注:E为单位矩阵。
使用逆矩阵求解线性方程组的方法:
两边都乘以$A^{-1}$,变成$A^{-1}$Ax=$A^{-1}$b,因为任何矩阵乘以单位矩阵都是自身,所以x=$A^{-1}$b
1、求解逆矩阵
2、验证矩阵和逆矩阵的乘积是单位矩阵
3、验证线性方程组
十八、Numpy将数组写到文件## Numpy怎样将数组读写到文件
本文档介绍的是Numpy以自己内建二进制的方式,将数组写出到文件,以及从文件加载数组;
如果是文本、表格类数据,一般使用pandas这个类库做加载和处理,不用numpy
几个方法:
1、np.load(filename):从.npy或者.npz文件中加载numpy数组
如果文件后缀是.npy返回单个数组,如果文件后缀是.npz返回多个数组的字典
2、np.save(filename, arr):将单个numpy数组保存到.npy文件中
3、np.savez(filename, arra=arra, arrb=arrb):将多个numpy数组保存到.npz未压缩的文件格式中
4、np.savez_compressed(filename, arra=arra, arrb=arrb):将多个numpy数组保存到.npz压缩的文件格式中
.npy和.npz都是二进制格式文件,用纯文本编辑器打开都是乱码
1、使用np.save和np.load保存和加载单个数组
2、使用np.savez和np.load保存和加载多个数组
3、使用np.savez_compressed和np.load保存和加载多个数组到压缩格式文件
十九、Numpy的结构化数组 一般情况下,Numpy中的数组都是同样的数据类型,比如int、float;
这也是Numpy性能高效的原因,在内存中紧凑存储,读取非常快;
但是Numpy也可以记录异构数组,比如下面的数据:
1、正常的Numpy数组的dtype值只有一个类型
2、怎样使用Numpy表达异构数据
3、针对异构数组的查询和操作
使用列表的方式查询一行
使用字典的方式查询一列
按条件查询
对单列做逐元素计算
最后的一言:
* 对于这种每列类型不同的“异构数据”,Pandas更擅长处理;
* 但我们还要学习一下Numpy结构化数组,不一定会使用它,但要能读懂别人的代码
Pandas是在Numpy基础上建立的非常流行的数据分析类库;
提供了强大针对异构、表格类型数据的处理与分析能力。
本次介绍Numpy和Pandas的转换方法:
Numpy数组怎样输入给Pandas的Series、Dataframe;Pandas的Series、Dataframe怎样转换成Numpy的数组
将Numpy数组转换成Pandas的数据结构
将Pandas的数据结构转换成Numpy数组
* 方法1:.values()
* 方法2:.to_numpy()
用途:
比如Scikit-Learn的模型输入需要的是Numpy的数组
可以使用Pandas对原始数据做大量的处理后,将结果数据转换成Numpy数组作为输入
二十一、Numpy数据输入给Sklearn实现模型训练
Numpy的数组怎样与sklearn模型交互,包括训练测试集拆分、输入给模型、评估模型、模型预估对于大家自己的任务,可以提前处理成这样的Numpy格式,然后输入给sklearn模型
import numpy as np# 使用sklearn自带的数据集,这些数据集都是Numpy的形式# 我们自己的数据,也可以处理成这种格式,然后就可以输入给模型from sklearn import datasets# 用train_test_split可以拆分训练集和测试集from sklearn.model_selection import train_test_split# 使用LinearRegression训练线性回归模型from sklearn.linear_model import LinearRegression
1、加载波斯顿房价数据集
2、拆分训练集和测试集
3、训练线性回归模型
4、评估模型和使用模型