机器学习入门到实战

1. 机器学习概述
1.1 人工智能应用场景

网络安全、电子商务、计算模拟、社交网络等……

1.2 人工智能概述
  • 人工智能发展的三要素:数据、算法和计算力
  • 计算力中的CPU和GPU的对比:CPU主要适合I/O密集型任务,GPU主要适合计算密集型任务。
  • 什么类型的程序适合在GPU上运行呢:计算密集型的程序、易于并行的程序
  • 计算密集型程序:所谓计算密集型(Compute-intension)的程序,就是其大部分事件花在寄存器运算上,寄存器的速度和处理器相当,从寄存器读写数据几乎没有延迟。
  • 易于并行的程序:GPU其实是一种SIMD(Single Instruction Multiple Data)架构,有成百上千个核,每一个核在同一时间最好能做同样的事情。
1.3 人工智能机器学习和深度学习

人工智能和机器学习、深度学习的关系:机器学习是人工智能的实现途径,深度学习是机器学习的一个方法发展出来的。

1.4 人工智能的起源
  • 图灵测试:测试者(人)与被测试者(机器)隔开的情况下,通过一些装置(如键盘)向被测试者随意提问。多次测试(一般是5min之内),如果有超过30%的测试者不能确定被测试者是人还是机器,那么这台机器就通过了测试,并认为具有人类智能
  • 达特茅斯会议:1958年8月,在美国汉诺斯小镇宁静的达特茅斯学院中,一些科学家讨论一个主题:用机器来模仿人类学习以及其它方面的智能。会议足足开了两个月的时间,虽然大家都没有达成普遍的共识,但是却为会议的内容命名为:人工智能。因此,1956年也就称为了人工智能元年。
1.5 人工智能发展的六个阶段

分别经历了起步发展期(1956~20世纪60年代初)、反思发展期(20世纪60年代~70年代初)、应用发展期(20世纪70年代初~80年代中)、低迷发展期(20世界80年代中~90年代中)、稳步发展期(20世纪90年代中期-2010年)、蓬勃发展期(2011年至今)。

1.6 人工智能主要分支
  • 计算机视觉:计算机视觉(CV)是指机器感知环境的能力,这一经典任务有图像形成、图像处理、图像提取和图像的三位推理。物体检测和人脸识别是其比较成功的研究领域。计算机视觉现在有很多应用,但是这项技术距影响社会阶段还有一定距离,要等到机器能在所有场景中都达到人类的同等水平才可以(感知其环境的所有相关方面)。
  • 语音识别:语音识别是指识别语音并将其转换成对应文本的技术。语音识别已经长期处于应用阶段了,随着大数据和深度学习技术的发展,语音识别进展得也很好,现在已经接近社会影响阶段
  • 文本挖掘和分类:这里的文本挖掘主要是指文本分类。该技术可用于理解、组织和分类结构化文本文档,涵盖的主要任务有句法分析、情绪分析和垃圾信息检测
  • 机器翻译:机器翻译(MT)是利用机器的力量自动将一种自然语言(源语言)的文本翻译成另一种语言(目标语言)。机器翻译领域最近由于神经机器翻译而取得非常显著的进展,但是仍然没有全面达到专业翻译人员的水平。
  • 机器人:机器人学研究的是机器人的设计、制造、运作和应用,以及控制他们的计算机系统、传感反馈和信息处理。机器人分为固定机器人移动机器人。固定机器人大量用于工业中,移动机器人被用于工业和家用(造价昂贵,所以发展不快)。
1.7 什么是机器学习

机器学习是从数据中自动分析模型,并利用模型对未来数据进行预测。

1.8 机器学习的流程
  • 获取数据:一行数据是一个样本,一列数据是一个特征。有些数据有目标值(标签值),有些数据没有目标值。有两种数据类型,一种是特征值+目标值(目标值是连续的、离散的),一种只有特征值,没有目标值。机器学习一般的数据集会划分为两个部分,分别是训练数据(用于训练,构建模型)、测试数据(在模型检验时用于评估模型是否有效)。
  • 数据的基本处理:对数据进行缺失值、去除异常值等处理。
  • 特征工程:特征工程是使用专业背景知识处理数据,使得特征在机器学习算法上发挥更好作用的过程,简单点来讲就是对数据的进一步处理,可以直接影响机器学习的效率。特征工程包括特征提取、特征预处理、特征降维。特征提取是将任意数据(如文本或图像)转换为可用于机器学习的数字特征。特征预处理是通过一些转换函数将特征数据转换成更适合算法模型的特征数据的过程。

数据和特征决定了机器学习的上限,模型和算法只是逼近这个上限而已。

  • 机器学习(模型训练):选择合适的算法对模型进行训练。
  • 模型评估:对训练好的模型进行评估,没有达到要求则重新上面的步骤,否则上线服务。
1.9 机器学习的算法分类

根据数据集组成不同,可以换将机器学习算法分为监督学习、无监督学习、半监督学习和强化学习。

  • 监督学习:输入数据是由输入特征值和目标值组成。函数的输出可以是一个连续的值,也可以是一个有限个离散值。连续对应的回归,离散对应的是分类。对于回归问题,如预测房价,根据样本集拟合出一条连续的曲线。对于分类问题,如根据肿瘤特征判断良性还是恶性,得到的结果是良性或者恶性,这是离散的。
  • 无监督学习:输入的数据是由特征值组成,没有目标值。输入数据没有被标记,也没有确定的结果。样本数据类型未知。需要根据样本间的相似性对样本集进行类别划分。

监督学习和无监督学习的对比:
在这里插入图片描述

  • 半监督学习:训练集同时包含有标记样本数据和未标记样本数据,也就是说训练集同时包含有目标值数据和没有目标值数据
  • 强化学习:实质是自动进行决策,并且可以做连续决策。强化学习的目标就是获得最多的累计奖励

监督学习和强化学习的对比:

N/A 监督学习 强化学习
反馈映射 输出的是之间的关系,可以告诉算法什么样的输入对应着什么样的输出 输出的是给机器的反馈,用来判断这个行为是好是坏
反馈时间 做了比较坏的选择立刻反馈给算法 结果反馈有延时,有时候可能需要走了很多步以后才知道以前的某一步的选择是好是坏
输入特征 输入的是独立同分布 面对的输入总是在变化的,每当算法做出一个行为,就会影响下一次决策的输入

独立同分布:输入空间中的所有样本服从一个隐含未知的分布,训练数据所有样本都是独立从这个样本上采集的。

四种学习分类的对比:

N/A 输入 输出 目的 案例
监督学习 有目标值 有反馈 预测结果 猫狗分类、房价预测
无监督学习 无目标值 无反馈 发现潜在结构 物以类聚,人以群分
半监督学习 部分有目标值,部分没有目标值 降低数据标记的难度
强化学习 决策流程和激励系统 一系列行动 长期利益最大化 学下期
1.10 模型评估

评估的方式:

  • 分类模型评估:首先知道评价指标准确率的概念,准确率是用来预测正确的数据占据数据总数的比例。其它的评价指标有精确率、召回率、F1-score、AUC指标等。
  • 回归模型评估:首先要知道均方根误差RMSE(Root Mean Squared Error),RMSE是一个衡量回归模型误差率的常用公式。不过,它仅能比较误差是相同单位的模型。其它的评价指标有相对平方误差(Relative Squared Error,RSE)、平均绝对误差(Mean Absolute Error,MAE)、相对绝对误差(Relative Absolute Error,RAE)。

对于评估的表现,就是一个拟合的问题。模型评估用于评价训练好的模型的表现效果,其表现效果大致可以两类,一类是过拟合,另一类是欠拟合。

  • 欠拟合:模型学习的太过粗糙,训练集中的样本数据特征关系没有表现出来
  • 过拟合:所建的机器学习模型或者深度学习模型在训练样本中表现过于优越,导致在测试数据集表现不好。

训练数据很好,误差也不大,为什么在测试集上还会有问题?其实,是过拟合的原因。

1.11 AML学习模型搭建实验

AML(Azure Machine Learning)是Microsoft在其公有云Azure上推出的给予Web使用的一项机器学习服务。机器学习是人工智能的一个分支,借助算法让计算机对大量流动数据集进行识别,这种方式能够通过历史数据来预测未来事件和行为,实现方式是优于传统的商业智能模式。Microsoft的目标是简化机器学习的过程,以便于开发人员、业务分析师和数据科学家进行广泛、便捷地应用。这款服务的目的是将机器学习动力与云计算做简单结合

1.12 什么是深度学习

深度学习(Deep Learning)也叫作深度结构学习(Deep Structured Learning)、层次学习(Hierarchical Learning)或深度机器学习(Deep Machine Learning),是一类算法集合,是机器学习的一个分支。深度学习近几年来,在会话识别、凸显识别和对象侦测等领域表现出惊人的准确性。深度学习各层负责的内容:

  • 1层:负责识别颜色和简单的纹理
  • 2层:一些神经元可以识别更加细化的纹理、布纹、刻纹、叶纹等
  • 3层:一些神经元负责感受黑夜里黄色烛光、高光、萤火、鸡蛋黄色等
  • 4层:一些神经元识别宠物的样貌、圆柱体事物、七星瓢虫等
  • 5层:一些神经元负责识别花、黑眼圈的动物、鸟、键盘、原型屋顶等
2. 开发工具的准备
2.1 Jupyter Notebook简介

jupyter项目是一个非盈利开源项目,源于2014年的IPython项目。Jupyter Notebook原名是IPython Notebook,是IPython的加强网页版,一个开源的Web应用程序。名字源于Julia、Python和R语言(数据科学三种语言),是一款程序员和科学工作者的编程、文档、笔记、展示软件。其保存的后缀名是.ipynb,这种文件格式是用于计算型叙述的JSON文档格式

2.2 Jupyter Notebook的优势

实时运行代码、叙述性的文本和可视化被整合到一起,方便使用代码和数据来讲述故事。与Pycharm对比,Pycharm适合目标明确且工程比较大、目录结构难管理的项目,而Jupyter Notebook适合简单的探索性的项目。此外,Jupyter Notebook在绘图和数据展示方面有着很大的优势。绘图方面,Jupyter Notebook可以在写代码的过程中展示图形,而Pycharm中需要把整个代码运行完之后才可以展示。数据方面,Jupyter Notebook展示更加美观,看起来更舒服。

2.3 Jupyter Notebook的简单使用

启动Jupyter Notebook:

# 激活虚拟环境
thanlon@thanlon-master:~$ source PycharmProjects/venv/machine-learning/bin/activate
(machine-learning) thanlon@thanlon-master:~$ 
# 启动Jupyter Notebook
(machine-learning) thanlon@thanlon-master:~$ jupyter notebook
[I 10:45:05.364 NotebookApp] 启动notebooks 在本地路径: /home/thanlon/PycharmProjects/venv/machine-learning/bin
[I 10:45:05.364 NotebookApp] 本程序运行在: http://localhost:8888/?token=24419c9887c275510be4fa3ef71b7656db1771177c29ce5d
[I 10:45:05.364 NotebookApp]  or http://127.0.0.1:8888/?token=24419c9887c275510be4fa3ef71b7656db1771177c29ce5d
[I 10:45:05.365 NotebookApp] 使用control-c停止此服务器并关闭所有内核(两次跳过确认).
[C 10:45:05.381 NotebookApp] 
    
    To access the notebook, open this file in a browser:
        file:///home/thanlon/.local/share/jupyter/runtime/nbserver-1761-open.html
    Or copy and paste one of these URLs:
        http://localhost:8888/?token=24419c9887c275510be4fa3ef71b7656db1771177c29ce5d
     or http://127.0.0.1:8888/?token=24419c9887c275510be4fa3ef71b7656db1771177c29ce5d

创建Python3文件:
在这里插入图片描述
运行Python3代码:
在这里插入图片描述
详细了解Jupyter Notebook的具体使用细节可以自行Google或者Baidu,网上学习文档很多,这里不再赘述。

3. 机器学习基础环境搭建

创建Python虚拟环境,构建项目:
在这里插入图片描述
激活虚拟环境,安装机器学习相关库:

pip3 install matplotlib pandas numpy jupyter table  -i https://pypi.tuna.tsinghua.edu.cn/simple 

在这里插入图片描述

4. Matplotlib
4.1 初识Matplotlib

Matplotlib是一种可视化工具,可视化工具是数据挖掘中的关键辅助工具,可以清晰地将数据展现给我们,帮助我们调整分析方法。Matplotlib能够将数据进行可视化,更加直观的呈现给我们,使数据更加客观、更具有说服力。

4.2 基础图像的绘制

matplotlib.pyplot模块包含了一系列类似于matlab的画图函数,使用的时候只需要导入:import matplotlib.pyplot as plt

图形回执流程:

  • 创建画布:plt.figure()
  • 绘制图像:plt.plot(x,y)
  • 显示图像:plt.show()

例1:展示上海一周的天气温度

参考代码:

import matplotlib.pyplot as plt
# 创建画布
plt.figure(figsize=(8,4),dpi=100)
# 绘制上海一周的天气温度折线图
plt.plot([1,2,3,4,5,6,7],[11,13,15,17,8,4,3])
# 显示图像
plt.show()

绘制的效果图:
在这里插入图片描述
例2:画出某城市11点~12点这1小时内的每分钟的温度变化折线图,温度范围在15~18度之间(某城市温度变化图)

参考代码:

# 导入所需要模块
import random,matplotlib.pyplot as plt
# 数据准备
x = range(60)
y = [random.uniform(15,18) for i in x]
# 创建画布
plt.figure(figsize=(8,4),dpi=100)
# 绘制图像
plt.plot(x,y)
# 展示图像
plt.show()

绘制的效果图:
在这里插入图片描述
例3:添加自定义x和y刻度

  • x要显示的刻度:plt.xticks(x,**kwargs)
  • y要显示的刻度:plt.xticks(y,**kwargs)

参考代码:

# 导入模块
import random
import  matplotlib.pyplot as plt
# 数据准备
x = range(60)
y = [random.uniform(15,18) for i in x]
# 绘制画布
plt.figure(figsize=(8,4),dpi=100)
# 绘图图像
plt.plot(x,y)
# 构造x轴刻度标签
x_ticks_lable = ['12点{}分'.format(i) for i in x]
# 构造y轴刻度标签
y_ticks_lable =  x
# 修改x,y轴坐标的刻度显示
plt.xticks(x[::5],x_ticks_lable[::5]) # 坐标的刻度不可以通过字符串刻度进行修改,注意先修改成数字,再用字符串进行替换
plt.yticks(y_ticks_lable[::5])
# 图像显示
plt.show()

绘制的效果图:
在这里插入图片描述
matplotlib是支持中文的,只是在配置信息里没有中文字体的相关信息。所以,我们需要解决中文显示的问题,解决方案1(这里使用ubuntu linux平台为例):

# 下载simhei字体
thanlon@thanlon-master:~$ wget http://z1.zhaodll.com:81/font/s/simhei.ttf.zip
thanlon@thanlon-master:~$ unzip simhei.ttf.zip
# 将字体拷贝到/usr/share/fonts/目录下
thanlon@thanlon-master:~$ sudo cp simhei.ttf /usr/share/fonts/
# 激活虚拟环境
thanlon@thanlon-master:~$ source PycharmProjects/venv/machine-learning/bin/activate
# 查看matplotlib配置文件的位置和配置文件的名称
(machine-learning) thanlon@thanlon-master:~$ ipython
Python 3.7.5 (default, Nov 20 2019, 09:21:52) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.11.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import matplotlib as mpl                                                                              

In [2]: mpl.get_configdir()                                                                                   
Out[2]: '/home/thanlon/.config/matplotlib'

In [3]: mpl.matplotlib_fname()                                                                                
Out[3]: '/home/thanlon/.config/matplotlib/matplotlibrc'

In [4]: 
# 创建配置文件
thanlon@thanlon-master:~$ vim .config/matplotlib/matplotlibrc
# 键入下面的内容,记得重启电脑生效
thanlon@thanlon-master:~$ cat .config/matplotlib/matplotlibrc
font.family:sans-serif
font.sans-serif:SimHei
axes.unicode_minus:False

成功解决中文显示问题:
在这里插入图片描述
解决方案2:
在Python脚本中动态设置matplotlibrc,可以避免由于改变配置带来的问题。有时候,字体更改后会导致坐标轴中的部分字符无法显示,此时需要更改axes.unicode_minus参数:

# 导入模块
import random
import  matplotlib.pyplot as plt
from pylab import mpl
# 设置中文字体
mpl.rcParams['font.sans-serif'] = ['SimHei']
#  设置正常显示符号
mpl.rcParams['axes.unicode_minus'] = False
# 数据准备
x = range(60)
y = [random.uniform(15,18) for i in x]
# 绘制画布
plt.figure(figsize=(8,4),dpi=100)
# 绘图图像
plt.plot(x,y)
# 构造x轴刻度标签
x_ticks_lable = ['12点{}分'.format(i) for i in x]
# 构造y轴刻度标签
y_ticks_lable =  x
# 修改x,y轴坐标的刻度显示
plt.xticks(x[::5],x_ticks_lable[::5]) # 坐标的刻度不可以通过字符串刻度进行修改
plt.yticks(y_ticks_lable[::5])
# 图像显示
plt.show()

例4:以网格的方式显示

参考代码:

# 导入模块
import random
import  matplotlib.pyplot as plt
# 数据准备
x = range(60)
y = [random.uniform(15,18) for i in x]
# 绘制画布
plt.figure(figsize=(8,4),dpi=100)
# 绘图图像
plt.plot(x,y)
# 构造x轴刻度标签
x_ticks_lable = ['12点{}分'.format(i) for i in x]
# 构造y轴刻度标签
y_ticks_lable =  x
# 修改x,y轴坐标的刻度显示
plt.xticks(x[::5],x_ticks_lable[::5]) # 坐标的刻度不可以通过字符串刻度进行修改
plt.yticks(y_ticks_lable[::5])
plt.grid(True,linestyle = '--',alpha = 0.5) # True表示显示;linestyle表示显示的方式,如这里的虚线;alpha表示图形的透明度
# 图像显示
plt.show()

绘制的效果图:
在这里插入图片描述
例5:添加描述信息,添加x和y轴以及标题的描述信息,设置图像中字体的大小显示

参考代码:

# 导入模块
import random
import  matplotlib.pyplot as plt
# 数据准备
x = range(60)
y = [random.uniform(15,18) for i in x]
# 绘制画布
plt.figure(figsize=(8,4),dpi=120)
# 绘图图像
plt.plot(x,y)
# 构造x轴刻度标签
x_ticks_lable = ['12点{}分'.format(i) for i in x]
# 构造y轴刻度标签
y_ticks_lable =  x
# 修改x,y轴坐标的刻度显示
plt.xticks(x[::10],x_ticks_lable[::10]) # 坐标的刻度不可以通过字符串刻度进行修改
plt.yticks(y_ticks_lable[::5])
plt.grid(True,linestyle = '--',alpha = 0.5) # True表示显示;linestyle表示显示的方式,如这里的虚线;alpha表示图形的透明度
plt.xlabel('时间',fontsize=10) # 设置x轴描述信息和字体大小
plt.ylabel('温度',fontsize=10) # 设置y轴描述信息和字体大小
plt.title('中午12点整到13点整之间的温度变化',fontsize=10) # 设置标题轴描述信息和字体大小
# 图像显示
plt.show()

绘制的效果图:
在这里插入图片描述
例6:图像保存
图像保存使用到 plt.savefig('tmp.png'),在使用plt.show()显示图像后会figure资源,所以在显示图像之后保存图像,就会保存一个空的图像。所以,我们需要在显示图像之前保存图像。
参考代码:

# 导入模块
import random
import  matplotlib.pyplot as plt
# 数据准备
x = range(60)
y = [random.uniform(15,18) for i in x]
# 绘制画布
plt.figure(figsize=(8,4),dpi=120)
# 绘图图像
plt.plot(x,y)
# 构造x轴刻度标签
x_ticks_lable = ['12点{}分'.format(i) for i in x]
# 构造y轴刻度标签
y_ticks_lable =  x
# 修改x,y轴坐标的刻度显示
plt.xticks(x[::10],x_ticks_lable[::10]) # 坐标的刻度不可以通过字符串刻度进行修改
plt.yticks(y_ticks_lable[::5])
plt.grid(True,linestyle = '--',alpha = 0.5) # True表示显示;linestyle表示显示的方式,如这里的虚线;alpha表示图形的透明度
plt.xlabel('时间',fontsize=10) # 设置x轴描述信息和字体大小
plt.ylabel('温度',fontsize=10) # 设置y轴描述信息和字体大小
plt.title('中午12点整到13点整之间的温度变化',fontsize=10) # 设置标题轴描述信息和字体大小
# 保存图像
plt.savefig('/home/thanlon/tmp.png') # 保存到制定目录
# 图像显示
plt.show()

绘制的效果图与例5是一致的,这里查看一下保存的图像:
在这里插入图片描述
例7:在一个坐标系中绘制多个图像

参考代码:

# 导入模块
import random
import  matplotlib.pyplot as plt
# 数据准备
x = range(50)
y = [random.uniform(15,18) for i in x]
# 绘制画布
plt.figure(figsize=(8,4),dpi=120)
# 绘图上海温度的折线图
plt.plot(x,y)
# 再增加一条北京的温度的数据
y_shanghai = [random.uniform(20,30) for i in x]
# 绘制北京温度的折线图
plt.plot(x,y_shanghai) # r表示红色,linestyle如果是空字符串,不会显示图像
# 构造x轴刻度标签
x_ticks_lable = ['12点{}分'.format(i) for i in x]
# 构造y轴刻度标签
y_ticks_lable =  x
# 修改x,y轴坐标的刻度显示
plt.xticks(x[::10],x_ticks_lable[::10]) # 坐标的刻度不可以通过字符串刻度进行修改
plt.yticks(y_ticks_lable[::5])
plt.grid(True,linestyle = '--',alpha = 0.5) # True表示显示;linestyle表示显示的方式,如这里的虚线;alpha表示图形的透明度
plt.xlabel('时间',fontsize=10) # 设置x轴描述信息和字体大小
plt.ylabel('温度',fontsize=10) # 设置y轴描述信息和字体大小
plt.title('上海市和北京市中午12点到13点之间的温度变化',fontsize=10) # 设置标题轴描述信息和字体大小
# 保存图像
# plt.savefig('/home/thanlon/tmp.png') # 保存到指定目录
# 图像显示
plt.show()

绘制的效果图:
在这里插入图片描述
例8:在一个坐标系中绘制多个图像并设置图像风格

颜色字符:r表示红色,g表示绿色,b表示蓝色,w表示白色,c表示青色,m表示洋红,y表示黄色,k表示黑色。

风格-表示实线,- -表示虚线,-.表示点划线,:表示点虚线,''表示留空、空格。

参考代码:

# 导入模块
import random
import  matplotlib.pyplot as plt
# 数据准备
x = range(50)
y = [random.uniform(15,18) for i in x]
# 绘制画布
plt.figure(figsize=(8,4),dpi=120)
# 绘图上海温度的折线图
plt.plot(x,y)
# 再增加一条北京的温度的数据
y_shanghai = [random.uniform(20,30) for i in x]
# 绘制北京温度的折线图
plt.plot(x,y_shanghai,linestyle=':',color='r') # r表示红色,linestyle如果是空字符串,不会显示图像
# 构造x轴刻度标签
x_ticks_lable = ['12点{}分'.format(i) for i in x]
# 构造y轴刻度标签
y_ticks_lable =  x
# 修改x,y轴坐标的刻度显示
plt.xticks(x[::10],x_ticks_lable[::10]) # 坐标的刻度不可以通过字符串刻度进行修改
plt.yticks(y_ticks_lable[::5])
plt.grid(True,linestyle = '--',alpha = 0.5) # True表示显示;linestyle表示显示的方式,如这里的虚线;alpha表示图形的透明度
plt.xlabel('时间',fontsize=10) # 设置x轴描述信息和字体大小
plt.ylabel('温度',fontsize=10) # 设置y轴描述信息和字体大小
plt.title('上海市和北京市中午12点到13点之间的温度变化',fontsize=10) # 设置标题轴描述信息和字体大小
# 保存图像
# plt.savefig('/home/thanlon/tmp.png') # 保存到指定目录
# 图像显示
plt.show()

绘制的效果图:
在这里插入图片描述
例9:在一个坐标系中绘制多个图像并添加图例

位置的选择:

位置字符串 位置代码
best 0
upper right 1
upter left 2
lower left 3
lower right 4
right 5
center left 6
center right 7
lower center 8
upper center 9
center 10

参考代码:

# 导入模块
import random
import  matplotlib.pyplot as plt
# 数据准备
x = range(45)
y = [random.uniform(15,18) for i in x]
# 绘制画布
plt.figure(figsize=(8,4),dpi=120)
# 绘图上海温度的折线图
plt.plot(x,y,label='上海')
# 再增加一条北京的温度的数据
y_shanghai = [random.uniform(20,30) for i in x]
# 绘制北京温度的折线图
plt.plot(x,y_shanghai,linestyle=':',color='r',label='北京') # r表示红色,linestyle如果是空字符串,不会显示图像
# 构造x轴刻度标签
x_ticks_lable = ['12点{}分'.format(i) for i in x]
# 构造y轴刻度标签
y_ticks_lable =  x
# 修改x,y轴坐标的刻度显示
plt.xticks(x[::10],x_ticks_lable[::10]) # 坐标的刻度不可以通过字符串刻度进行修改
plt.yticks(y_ticks_lable[::5])
plt.grid(True,linestyle = '--',alpha = 0.5) # True表示显示;linestyle表示显示的方式,如这里的虚线;alpha表示图形的透明度
plt.xlabel('时间',fontsize=10) # 设置x轴描述信息和字体大小
plt.ylabel('温度',fontsize=10) # 设置y轴描述信息和字体大小
plt.title('上海市和北京市中午12点到13点之间的温度变化',fontsize=10) # 设置标题轴描述信息和字体大小
# 显示图例
plt.legend(loc='best') # 自动选择最好的位置显示
# 保存图像
# plt.savefig('/home/thanlon/tmp.png') # 保存到指定目录
# 图像显示
plt.show()

绘制的效果图:
在这里插入图片描述
例 10:在多个坐标系中绘制多个图像

参考代码:

# 导入模块
import matplotlib.pyplot as plt
import random
# 准备数据
x = range(45)
y_shanghai = [random.uniform(15,20) for i in x]
y_beijing  = [random.uniform(20,30) for i in x]
# 创建画布
fig,axes = plt.subplots(nrows=1,ncols=2,figsize=(16,5),dpi=100)
# 绘制图像
axes[0].plot(x,y_shanghai,label = '上海')
axes[1].plot(x,y_beijing,label='北京',color='r',linestyle='--')
# 添加x与y轴的刻度
x_ticks_label = ['12点{}分'.format(i) for i in x] 
axes[0].set_xticks(x[::5])
axes[0].set_yticks(x[::5])
axes[0].set_xticklabels(x_ticks_label[::5])
axes[1].set_xticks(x[::5])
axes[1].set_yticks(x[::5])
axes[1].set_xticklabels(x_ticks_label[::5])
# 添加网格显示
axes[0].grid(True,linestyle='--',alpha=0.5)
axes[1].grid(True,linestyle='--',alpha=0.5)
# 显示图例
axes[0].legend(loc=0)
axes[1].legend(loc=0)
# 添加描述信息
axes[0].set_xlabel('时间')
axes[0].set_ylabel('温度')
axes[0].set_title('中午12点到13点上海的温度变化图',fontsize = 15)
axes[1].set_xlabel('时间')
axes[1].set_ylabel('温度')
axes[1].set_title('中午12点到13点北京的温度变化图',fontsize = 15)
# 图像保存
plt.savefig('/home/thanlon/tmp.png')
# 显示图像
plt.show()

绘制的效果图:
在这里插入图片描述

4.3 常见图像的绘制

Matplotlib能够绘制折线图、散点图、柱状图、直方图、饼图。在选择以何种方式展示数据时,我们需要明确各种统计图的意义。

折线图:以折线的上升或下降来表示统计数量的增减变化的统计图。特点是能够显示数据的变化趋势,反应事物的变化情况。使用的的方法是:matplotlib.pyplot.plot(*args, scalex=True, scaley=True, data=None, **kwargs)

参考代码:

# 导入相关模块
import matplotlib.pyplot as plt
import random
# 准备数据
x = range(9)
y = [random.randint(0,9) for i in x]
# 绘制画布
plt.figure(figsize=(8,4),dpi=100)
# 添加x,y刻度的显示
plt.xticks(x[::1])
plt.yticks(x[::1])
# 绘制图像
plt.plot(x,y)
# 添加网格显示
plt.grid(True,linestyle='--',alpha=0.5)
# 图像保存
plt.savefig('/home/thanlon/tmp.png')
# 图像显示
plt.show()

折线图的效果图:
在这里插入图片描述
散点图:用两组数据构成多个坐标点,考察坐标点的分布,判断了两变量之间是否存在某种关联,以及总结坐标点的分布模式。使用到的方法是:matplotlib.pyplot. scatter ( x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, edgecolors=None, hold=None, data=None, **kwargs )

参考代码:

# 导入相关模块
import matplotlib.pyplot as plt
import random
# 准备数据
x = range(40)
y = [random.randint(1,49) for i in x]
# 绘制画布
plt.figure(figsize=(10,4),dpi=100)
# 添加x,y轴刻度的显示
plt.xticks(x[::1])
plt.yticks(range(50)[::5])
# 设置图像的标题
plt.title('常见图像的之散点图的绘制')
# 绘制图像
plt.scatter(x,y)
# 图像的显示
plt.show()

散点图的效果图:
在这里插入图片描述
柱状图:排列在工作表的列或行中的数据可以绘制到柱状图中,特点是很容易看出数据的大小,适用于统计和对比数据。使用的方法是:matplotlib.pyplot. bar ( left, height, width=0.8, bottom=None, hold=None, data=None, **kwargs )

参考代码:

import matplotlib.pyplot as plt
# 数据的准备
x_movie_names = ['唐人街探案3', '姜子牙', '囧妈', '中国女排', '紧急救援', '熊出没·狂野大陆', '急先锋', '我在时间尽头等你', '妙先生', '抵达之谜']
x = range(len(x_movie_names))
y = [722193, 357767, 246846, 169509, 168038, 93609, 84625, 32234, 29082, 22227]
# 绘制画布
plt.figure(figsize = (15, 5), dpi = 100)
# 绘制图像
plt.bar(x, y, color = ['b', 'r' , 'g', 'y', 'c', 'm', 'y', 'k', 'c', 'g'], width=0.6)
# 添加x,y刻度的显示
# plt.xticks(x[::1], x_movie_names[::1])
plt.xticks(x, x_movie_names)
# 设置标题
plt.title('猫眼电影最受期待榜榜单', fontsize = 15)
# 添加网格
plt.grid(True, linestyle='--', alpha=0.5)
# 图像的显示
plt.show()

柱状图的效果图:
在这里插入图片描述
饼图:用于表示不同分类的占比情况,通过弧度大小来对比各种分类。使用函数是:matplotlib.pyplot.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, radius=None, counterclock=True, wedgeprops=None, textprops=None, center=(0, 0), frame=False, rotatelabels=False, *, data=None))

参考代码:

import matplotlib.pyplot as plt
# 绘制画布
plt.figure(figsize=(4,4), dpi=100)
# 绘制图像
plt.pie([1, 2, 3, 10, 6, 7], labels=['娱乐', '育儿', '饮食', '房贷', '交通', '其它'], colors=['b', 'r' , 'g', 'y', 'c', 'm'], explode=[0, 0, 0, 0.1, 0, 0], autopct='%1.1f%%', shadow=False, startangle=10)
# 设置标题
plt.title("2020年2月份家庭支出")
# 图像显示
plt.show()

饼图的效果图:
在这里插入图片描述

5. Numpy
5.1 Numpy简介

Numpy(Numerical Python)是一个开源的高性能的科学计算和数据分析库,用于快速处理任意维度的数组。并且,Numpy支持常见的数组和矩阵操作。Numpy使用ndarray对象来处理多为数组,ndarray对象是一个快速灵活的大数据容器。

5.2 ndarray简介

Python中有列表,可当数组使用。Python中也有array模块,但是不支持多维数组。并且列表和array模块都没有科学运算函数。所以,Python不适合做矩阵等科学计算。Numpy没有使用Python本身的数组机制,而是提供了ndarray这个n维数组类型对象,ndarray不仅能够很方便地对数组进行存取,而且拥有丰富的科学计算函数,如向量的加法、减法、乘法等。下面通过实例演示创建一个ndarray多维数组:

# 导入numpy函数库并指定库的别名
import numpy as np
# 创建一维数组
array1 = np.array([1, 2, 3, 4])
# 创建二维数组
array2 = np.array([[1, 2, 3, 4],[5, 6, 7, 8]])
# 创建三维数组
array3 = np.array([[[1, 2, 3, 4],[5, 6, 7, 8],[9, 10, 11, 12]],[[1, 2, 3, 4],[5, 6, 7, 8],[9, 10, 11, 12]]])
array1:array([1, 2, 3, 4])
array2:array([[1, 2, 3, 4],
       [5, 6, 7, 8]])
array3:array([[[ 1,  2,  3,  4],
        [ 5,  6,  7,  8],
        [ 9, 10, 11, 12]],

       [[ 1,  2,  3,  4],
        [ 5,  6,  7,  8],
        [ 9, 10, 11, 12]]])
5.3 ndarray与list执行效率的对比

使用Python的list可以作为一维数组,通过列表的嵌套可以实现多维数组。那为什么还要使用Numpy的ndarray,其实使用ndarray处理数组,其效率要比list要高很多,下面通过例子来比较下两者的执行效率:

import random
import numpy as np
# 定义一个空列表用于存放(数组)元素
lst = []
# 向lst中添加一千万个元素
for i in range(10000000):
    lst.append(random.random())
%time sum01 = sum(lst) # 使用Python中的sum函数对数组元素进行求和;%time是魔法方法,可以查看当前行代码运行一次需要花费的时间。
lst2 = np.array(lst) # 将lst的存储方式转换成ndarray中的存储方式
%time sum02 = np.sum(lst2) # 使用ndarray中的sum对同样的数组进行求和
第一次运行上面的代码:
CPU times: user 40.8 ms, sys: 70 µs, total: 40.8 ms
Wall time: 40.9 ms
CPU times: user 4.07 ms, sys: 0 ns, total: 4.07 ms
Wall time: 3.87 ms

第一次运行上面的代码:
CPU times: user 41.1 ms, sys: 0 ns, total: 41.1 ms
Wall time: 41.1 ms
CPU times: user 3.86 ms, sys: 0 ns, total: 3.86 ms
Wall time: 3.87 ms

第三次运行上面的代码:
CPU times: user 40.8 ms, sys: 87 µs, total: 40.9 ms
Wall time: 40.9 ms
CPU times: user 4.23 ms, sys: 31 µs, total: 4.26 ms
Wall time: 4.07 ms

很明显使用numpy的ndarray对数组求和的效率要比原生Python的sum函数求和高10倍以上。机器学习最大的特点是需要对大量的数据做运算,如果没有一个快速的解决方案,那么可能Python在机器学习领域就达不到很好的效果。Numpy专门对ndarray的操作和运算进行设计,所以,数组的存储效率和输入输出性能远优于Python中的嵌套列表。数组越大,Numpy的优势就越明显。

5.4 ndarray的优势
  • 内存块风格:ndarray在存储数据的时候是直接存储,Python的list中的数据不是直接存储,需要先找寻一个地址,然后通过地址找到需要的内容。ndarray中的所有元素的类型都是相同的,所以ndarray在存储元素时,内存是可以连续的。而Python中list中的元素是任意的,所以只能通过寻址的方式找到下一个元素。ndarray在通用性上要输于list,但在科学计算中,Numpy的ndarray就可以省掉很多循环语句,代码使用方面比Python的list要简洁。
  • ndarray支持并行化运算(向量化运算):Numpy内置并行运算功能,当系统有多个核心时,做运算会自动做并行运算。
  • 效率远高于纯Python代码,Numpy底层使用C语言编写,内部解除GIL(全局解释器锁),其对数组的操作速度不受Python GIL的影响。
5.5 ndarray数组的属性

数组的维度:

# 导入numpy模块并为模块设置别名
import numpy as np
# 创建一个维度是3行4列的ndarray数组
array01 = np.array([
    [80, 78, 98, 88],
    [89, 87, 89, 78],
    [78, 84, 89, 87]
])
array01.shape
Out[](3, 4)

数组的维数:

# 导入numpy模块并为模块设置别名
import numpy as np
# 创建一个维度是3行4列的ndarray数组
array01 = np.array([
    [80, 78, 98, 88],
    [89, 87, 89, 78],
    [78, 84, 89, 87]
])
array01.ndim
Out[]2

数组中的元素数量:

# 导入numpy模块并为模块设置别名
import numpy as np
# 创建一个维度是3行4列的ndarray数组
array01 = np.array([
    [80, 78, 98, 88],
    [89, 87, 89, 78],
    [78, 84, 89, 87]
])
array01.size
Out[]12

一个数组元素的长度(字节):

# 导入numpy模块并为模块设置别名
import numpy as np
# 创建一个维度是3行4列的ndarray数组
array01 = np.array([
    [80, 78, 98, 88],
    [89, 87, 89, 78],
    [78, 84, 89, 87]
])
array01.itemsize
Out[]8

数组元素的类型:

# 导入numpy模块并为模块设置别名
import numpy as np
# 创建一个维度是3行4列的ndarray数组
array01 = np.array([
    [80, 78, 98, 88],
    [89, 87, 89, 78],
    [78, 84, 89, 87]
])
array01.dtype
Out[]:dtype('int64')
5.6 ndarray数组的形状

一维数组:

import numpy as np
a = np.array([1, 2, 3, 4, 5])
print(a)
print(a.shape)
[1 2 3 4 5]
(5,) # 表示一维数组,5:数组中有5个元素

二维数组:

import numpy as np
b = np.array([
    [1, 2, 3, 4, 5],
    [4, 5, 6, 7, 8]
])
print(b)
print(b.shape)
[[1 2 3 4 5]
 [4 5 6 7 8]]
(2, 5) # 有两个元素,表示的是二维数组。2:二维数组中有两个一维数组;5:一维数组中有5个元素

三维数组(三维数组是二维数组的叠加):

import numpy as np
c = np.array([
    [[1, 2, 3, 4, 5],
    [4, 5, 6, 7, 8]],
    [[9, 10, 11, 12, 13],
    [14, 15, 16, 17, 18]]
])
print(c)
print(c.shape)
[[[ 1  2  3  4  5]
  [ 4  5  6  7  8]]
 [[ 9 10 11 12 13]
  [14 15 16 17 18]]]
(2, 2, 5) # 第一个2:有2个二维数组;第二个2:二维数组中有2个一维数组;3:在一维数组中有3个元素
5.7 ndarray数组的类型

不指定数组类型(整型):

import numpy as np
a = np.array([
    [[1, 2, 3, 4, 5, 6],
    [7, 8, 9, 10, 11,12],
    [12, 13, 14, 15, 16,17]],
    [[1, 2, 3, 4, 5, 6],
    [7, 8, 9, 10, 11,12],
    [12, 13, 14, 15, 16,12]]
])
a.dtype
dtype('int64')

不指定数组类型(小数):

import numpy as np
a = np.array([
    [[1.1, 2, 3, 4, 5, 6],
    [7, 8, 9, 10, 11,12],
    [12, 13, 14, 15, 16,17]],
    [[1, 2, 3, 4, 5, 6],
    [7, 8, 9, 10, 11,12],
    [12, 13, 14, 15, 16,12]]
])
a.dtype
dtype('float64')

如果不指定,整型默认是int64,小数默认是float64。如果指定数组类型:

指定数组类型,将整型指定为float64类型:

import numpy as np
a = np.array([
    [[1, 2, 3, 4, 5, 6],
    [7, 8, 9, 10, 11,12],
    [12, 13, 14, 15, 16,17]],
    [[1, 2, 3, 4, 5, 6],
    [7, 8, 9, 10, 11,12],
    [12, 13, 14, 15, 16,12]]
], dtype=np.float64)
print(a)
a.dtype
[[[ 1.  2.  3.  4.  5.  6.]
  [ 7.  8.  9. 10. 11. 12.]
  [12. 13. 14. 15. 16. 17.]]

 [[ 1.  2.  3.  4.  5.  6.]
  [ 7.  8.  9. 10. 11. 12.]
  [12. 13. 14. 15. 16. 12.]]]
dtype('float64')

不指定数组类型(字符串):

import numpy as np
a = np.array(['I', 'Like' ,'qianqian'])
a
array(['I', 'Like', 'qianqian'], dtype='<U8')

指定数组类型(字符串):

import numpy as np
a = np.array(['I', 'Like' ,'qianqian'], dtype=np.string_)
a
array([b'I', b'Like', b'qianqian'], dtype='|S8') # S:String;8:数组中最长字符串是8个字母
5.8 ndarray数组的生成

从已存在的数组中生成数组的两种方法,numpy.arraynumpy.asarray方法,下面通过一个小案例来区别这两种方法:

首先创建一个数组作为已存在数组:

import numpy as np
a = np.array([[1, 2, 3, 4, 5, 6],[7,8,9,10,11,112]])
a
array([[  1,   2,   3,   4,   5,   6],
       [  7,   8,   9,  10,  11, 112]])

使用array在原有数组的基础上生成数组(深度拷贝):

a1 = np.array(a) # 深拷贝
a1[0, 0] = 0
a
array([[  1,   2,   3,   4,   5,   6],
       [  7,   8,   9,  10,  11, 112]])

使用asarray在原有数组的基础上生成数组:(浅拷贝)

a2 = np.asanyarray(a) # 浅拷贝
a2[0, 0] = 0
a
array([[  0,   2,   3,   4,   5,   6],
       [  7,   8,   9,  10,  11, 112]])

生成固定范围的数组:

创建等差数列的数组,指定数量,使用的函数是:linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None,axis=0)

import numpy as np
arr = np.linspace(0,21,6) # start:0,序列的起始值; stop:20,序列的终止值; num:5, 要生成的等间隔样例数量, 默认是50。endpoint:序列中是否是否包含stop值,默认是True
arr
array([ 0. ,  4.2,  8.4, 12.6, 16.8, 21. ])

创建等差数列的数组,指定步长,使用的函数:arange(start=None, *args, **kwargs)

import numpy as np
arr = np.arange(0, 20, 2, dtype=np.int64) # step:2,步长;dtype:数据类型
arr
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])

创建等比数列,使用的函数:logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None,axis=0)

import numpy as np
# 注意这里是生成10的多少次方
arr = np.logspace(0, 2, 3) # num是要生成等比数列的数量;0、2的意思分别是10的0次方~10的2次方;3:生成3个数
arr
array([  1.,  10., 100.])

创建随机数组(正太分布方式),使用np.random模块创建正太分布有三种方式,分别是:randn(*dn),normal(loc=0.0, scale=1.0, size=None),standard_normal(size=None)。

  • randn:从标准动态分布中返回一个或多个样本值。
  • normal:返回指定形状的标准正太分布数组。loc:此动态分布的均值(对应着整个分布的中心);scale:概率分布的标准差,值越大越矮胖,反之越瘦高。size:输出的是shape,默认是None,只输出一个值。
  • standard_normal:返回指定形状的标准正太分布的数组

生成均值为1.75,标准差为1的100000000个正态分布数据。使用到的函数:normal(loc=0.0, scale=1.0, size=None)

# 导入相关模块
import numpy as np
import matplotlib.pyplot as plt
# 数据的准备
x = np.random.normal(1.75, 1, 100000000) # array是一维数组,也就是一个列表
# 创建画布
plt.figure(figsize=(8,4), dpi=100)
# 绘制图像(绘制直方图)
plt.hist(x, 1000) # 1000:1000组数据
# 显示图像
plt.show()

在这里插入图片描述
模拟生成一组股票的涨跌幅数据:随机生成4支股票1周的交易日涨幅数据(随机生成涨跌幅在某个正太分布内,如均值是0,方差是1):

import numpy as np
arr = np.random.normal(0, 1, (4,5))
arr
array([[ 1.39648189,  0.17949331, -0.0393186 ,  1.54571909, -0.89729191],
       [-1.30231063, -0.21940802,  0.43169118, -0.68724142, -1.11523206],
       [-1.93539031, -2.21212029, -1.39101401, -2.27047266, -0.1254774 ],
       [ 1.67693295, -2.22111556,  1.5863305 ,  0.69848128,  2.25766984]])

创建随机数组(均匀分布方式),使用np.random模块创建正太分布有三种方式,分别是:rand(*dn),uniform(low=0.0, high=1.0, size=None),randint(low, high=None, size=None, dtype=‘l’)

  • rand:返回[0.0,1.0)内的一组均匀分布的数。
  • uniform:从一个均匀分布[low=0.0, hegh=1.0, size=None)中随机采样,low是采用下界,float类型,默认是0;high是采样下界,float类型,默认值是1。size是输出样本的数目,int或元祖类型。如size=(m,n,k)则输出mnk个样本,缺省时输出1个值。返回值:ndarray类型,其形状和参数size中的描述一致。
  • randint:从一个均匀分布中随机采样,生成一个整数或N维整数数组。对于取数范围,如果high不是None时,取[low,high)之间的随机数,否则取值[low,high)之间随机整数。
# 导入模块
import numpy as np
# 准别数据,生成均匀分布的数据
x = np.random.uniform(-1, 1, 100000000)
# 创建画布
plt.figure(figsize=(8,4), dpi=100)
# 绘制图像(绘制直方图)
plt.hist(x, 1000) # 1000:1000组数据
# 显示图像
plt.show()

在这里插入图片描述

5.9 ndarray数组的索引和切片
  • 一维数组的索引和切片
import numpy as np
arr = np.array([1, 2, 3, 4])
print(arr)
arr[0]
[1 2 3 4]
1
  • 二维数组的索引和切片
import numpy as np
arr2 = np.array([[1, 2, 3, 4],[5, 6, 7, 8]])
print(arr2)
arr2[1,1]
[[1 2 3 4]
 [5 6 7 8]]
6
  • 三维数组的索引和切片
import numpy as np
arr3 = np.array([[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 21, 22, 23]]])
print(arr3)
arr3[1, 1, 1]
[[[ 1  2  3  4]
  [ 5  6  7  8]
  [ 9 10 11 12]]

 [[13 14 15 16]
  [17 18 19 20]
  [21 21 22 23]]]
18
5.10 ndarray数组形状的修改
  • reshape(self, shape, order='C ')函数的应用
import numpy as np
arr = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]])
# 打印这个数组的形状
print(arr.shape)
# 修改数组的形状
arr2 = arr.reshape([6, 3])
# 打印改变后数组的形状
print(arr2.shape)
arr2
(3, 6)
(6, 3)
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12],
       [13, 14, 15],
       [16, 17, 18]])

当不知到有多少列的时候:

import numpy as np
arr = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]])
# 打印这个数组的形状
print(arr.shape)
# 修改数组的形状
arr2 = arr.reshape([6, -1])
# 打印这个数组的形状
print(arr2.shape)
arr2
(3, 6)
(6, 3)
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12],
       [13, 14, 15],
       [16, 17, 18]])

当不知道有多少行的时候:

import numpy as np
arr = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]])
# 打印这个数组的形状
print(arr.shape)
# 修改数组的形状
arr2 = arr.reshape([-1, 2])
# 打印这个数组的形状
print(arr2.shape)
arr2
(3, 6)
(9, 2)
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10],
       [11, 12],
       [13, 14],
       [15, 16],
       [17, 18]])
  • resize(self, new_shape, refcheck=True)函数的应用,要区别与reshape方法,其返回结果并不是新的数组,而是把原来的数组给修改了
import numpy as np
arr = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]])
# 打印这个数组的形状
print(arr.shape)
# 修改数组的形状
arr.resize([2,8])
# 打印这个数组的形状
print(arr.shape)
arr
(3, 6)
(2, 8)
array([[ 1,  2,  3,  4,  5,  6,  7,  8],
       [ 9, 10, 11, 12, 13, 14, 15, 16]])
  • 数组的转置,将数组的行列进行互换,使用数组名.T
# 数组的转置
import numpy as np
arr = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]])
arr.T
array([[ 1,  7, 13],
       [ 2,  8, 14],
       [ 3,  9, 15],
       [ 4, 10, 16],
       [ 5, 11, 17],
       [ 6, 12, 18]])
5.11 ndarray数组类型的修改
  • ndarray.astype(type):返回修改类型之后的数组
# 返回修改了类型之后的数组
import numpy as np
arr = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]])
print(arr.dtype)
arr2 = arr.astype(np.float)
arr2
int64
array([[ 1.,  2.,  3.,  4.,  5.,  6.],
       [ 7.,  8.,  9., 10., 11., 12.],
       [13., 14., 15., 16., 17., 18.]])
  • ndarray.tostring([order])或者ndarray.tobytes([order]):构造包含数组原始数据字节的Python字节
# 构造包含数组原始数据字节的Python字节1
import numpy as np
arr = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]])
str_arr = arr.tostring()
str_arr
b'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00'
# 构造包含数组原始数据字节的Python字节2
import numpy as np
arr = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]])
str_arr = arr.tobytes()
str_arr
b'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00'
5.12 ndarray数组的去重

数组去重的方法是unique(ar, return_index=False, return_inverse=False,return_counts=False, axis=None):

# 返回修改了类型之后的数组
import numpy as np
arr = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 2, 10, 5, 6], [13, 14, 15, 16, 17, 18]])
arr2 = np.unique(arr)
arr2
array([ 1,  2,  3,  4,  5,  6,  7,  8, 10, 13, 14, 15, 16, 17, 18])
5.13 ndarray的运算
  • 逻辑运算
# 生成10名同学5门课程的分数
import numpy as np
scores = np.random.randint(50, 100, (10, 5))
# 取出最后4名同学的成绩,用于逻辑判断
ret1 = scores[6:, 0:5] # 或者scores[6:, 0:5] 
# 逻辑判断,如果成绩不小于60分,标记为True,否则为False
ret2 = ret1 > 60 # 返回的结果是标记后的
'''
array([[False,  True,  True,  True,  True],
       [ True,  True,  True,  True, False],
       [ True,  True, False,  True,  True],
       [ True,  True, False,  True,  True]])
'''
ret1[ret1 > 60] = 1
ret1
'''
array([[54, 51, 59,  1,  1],
       [ 1,  1,  1,  1,  1],
       [ 1,  1, 60,  1,  1],
       [57,  1,  1,  1,  1]])
'''
  • 通用判断函数

numpy.all方法:

'''
numpy.all方法是:只要有一个不满足条件,就返回False;所有都满足条件,返回True
判断前两名同学的成绩是否都及格
'''
import numpy as np
scores = np.random.randint(50, 100, (10, 5))
print(scores[0:2, :])
ret = np.all(scores[0:2, :] > 90)
ret
[[77 81 89 51 66]
 [78 64 53 53 70]]
False

numpy.any方法:

'''
numpy.any方法是:只要有一个满足条件,就返回True;所有都不满足条件返回False
判断前两名同学的成绩是否有不小于90分的
'''
import numpy as np
scores = np.random.randint(50, 100, (10, 5))
print(scores[0:2, :])
ret = np.any(scores[0:2, :] > 90)
ret
[[82 97 82 79 53]
 [54 81 91 67 64]]
True
  • 三元运算符

通过使用numpy.where能够进行更加复杂的运算:

# 将前四名学生的前四门课程中成绩中大于60的置为1,否则置为0
import numpy as np
scores = np.random.randint(50, 100, (10, 5))[:4, :4]
print(scores)
np.where(scores > 60, 1, 0)
[[76 84 84 52]
 [52 85 50 90]
 [57 71 93 92]
 [90 72 66 67]]
array([[1, 1, 1, 0],
       [0, 1, 0, 1],
       [0, 1, 1, 1],
       [1, 1, 1, 1]])

复合逻辑需要结合np.logical_and和np.logical_or使用:

# 将前四名学生前四门课程中成绩大于60且小于90的置为1,否知置为0
import numpy as np
scores = np.random.randint(50, 100, (10, 5))[:4, :4]
print(scores)
np.where(np.logical_and(scores > 60, scores < 90), 1, 0)
[[61 99 91 92]
 [78 80 78 56]
 [63 88 80 59]
 [84 79 65 86]]
array([[1, 0, 0, 0],
       [1, 1, 1, 0],
       [1, 1, 1, 0],
       [1, 1, 1, 1]])
# 将前四名学生前四门课程中成绩大于90或小于60的置为1,否知置为0
import numpy as np
scores = np.random.randint(50, 100, (10, 5))[:4, :4]
print(scores)
np.where(np.logical_or(scores > 90, scores < 60), 1, 0)
[[76 63 99 78]
 [84 85 74 56]
 [72 72 92 61]
 [56 54 89 60]]
array([[0, 0, 1, 0],
       [0, 0, 0, 1],
       [0, 0, 1, 0],
       [1, 1, 0, 0]])
5.14 ndrray统计运算相关的函数

max(a, axis)函数的使用:

# 取最大值
import numpy as np
scores = np.random.randint(50, 100, (10, 5))
print(scores)
np.max(scores)
[[82 51 86 57 79]
 [90 87 50 97 90]
 [81 93 72 69 90]
 [86 50 83 65 83]
 [68 66 78 59 65]
 [71 64 56 50 72]
 [79 69 91 97 76]
 [68 67 64 83 54]
 [66 63 60 58 53]
 [87 64 63 55 60]]
97

min(a, axis)函数的使用:

# 取最小值
import numpy as np
scores = np.random.randint(50, 100, (10, 5))
print(scores)
np.min(scores)
[[83 81 55 73 93]
 [57 61 51 60 91]
 [66 77 83 95 56]
 [75 76 58 59 96]
 [90 72 72 53 84]
 [83 67 93 82 57]
 [50 91 51 98 62]
 [83 53 91 78 91]
 [99 77 93 81 99]
 [89 71 73 81 87]]
50

mean(a, axis, dtype)函数的使用:

# 取平均值
import numpy as np
scores = np.random.randint(50, 100, (10, 5))
print(scores)
np.mean(scores)
[[50 90 77 76 78]
 [92 84 76 59 58]
 [77 69 66 73 68]
 [69 57 64 94 75]
 [82 52 97 93 57]
 [73 53 88 64 60]
 [84 98 64 65 88]
 [72 54 67 61 57]
 [99 83 73 80 64]
 [70 63 65 94 58]]
72.6

也可以按照行和列求解最大值、最小值、平均值等,下面以求解最大值、最小值为例子:

# 按照列求最大值
import numpy as np
scores = np.random.randint(50, 100, (10, 5))
print(scores)
np.max(scores, axis=0)  # axis=0表示按照列来求解
[[57 66 72 90 69]
 [85 90 98 95 71]
 [97 75 83 57 55]
 [81 77 95 92 61]
 [79 68 79 54 66]
 [50 52 95 52 96]
 [55 64 86 54 73]
 [63 67 78 56 84]
 [54 76 92 88 89]
 [52 79 75 91 62]]
array([97, 90, 98, 95, 96])
# 按照行求最大值
import numpy as np
scores = np.random.randint(50, 100, (10, 5))
print(scores)
np.max(scores, axis=1)  # axis=1表示按照行来求解
[[54 77 71 85 54]
 [65 89 95 69 75]
 [56 95 54 75 63]
 [62 84 58 94 89]
 [66 51 55 91 85]
 [70 97 75 70 84]
 [94 80 83 59 90]
 [76 70 55 99 74]
 [79 60 81 99 57]
 [96 82 50 57 80]]
array([85, 95, 95, 94, 91, 97, 94, 99, 99, 96])

argmax(a, axis)方法的使用:

# 最大值的下标
import numpy as np
scores = np.random.randint(50, 100, (10, 5))
print(scores)
np.argmax(scores)
[[67 73 95 94 92]
 [52 91 74 96 76]
 [82 70 61 86 81]
 [90 69 57 86 66]
 [50 53 85 69 65]
 [84 69 81 61 52]
 [69 61 65 91 70]
 [87 50 68 78 83]
 [72 93 62 79 89]
 [99 75 77 53 87]]
45
# 按列求最大值的下标
import numpy as np
scores = np.random.randint(50, 100, (10, 5))
print(scores)
np.argmax(scores, axis=0)
[[85 68 60 71 62]
 [65 71 86 60 84]
 [57 81 76 58 95]
 [57 83 66 73 55]
 [88 77 54 81 68]
 [78 53 54 99 54]
 [99 86 63 56 97]
 [92 96 52 83 57]
 [85 83 65 55 76]
 [79 77 67 63 69]]
array([6, 7, 1, 5, 6])
# 按行求最大值的下标
import numpy as np
scores = np.random.randint(50, 100, (10, 5))
print(scores)
np.argmax(scores, axis=1)
[[78 53 79 82 60]
 [61 92 72 56 61]
 [71 64 80 81 81]
 [95 55 81 85 74]
 [63 82 65 89 91]
 [94 62 52 61 93]
 [91 69 98 54 63]
 [76 53 93 86 83]
 [97 98 92 52 95]
 [70 60 75 83 74]]
array([3, 1, 3, 0, 4, 0, 2, 2, 1, 3])

argmin(a, axis)的使用同argmax(a, axis)的相似,统计运算中还可以求中位数[median(a, axis)]、平均值、标准差[std(a, axis, dtype)]和方差[var(a, axis, dtype)]等。

5.15 数组间的运算

数组与数之间的运算:

执行程序1:

import numpy as np
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
arr + 3 # 所有元素加3

打印结果:

array([[ 4,  5,  6,  7,  8],
       [ 9, 10, 11, 12, 13]])

执行程序2:

import numpy as np
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
arr / 2 # 所有元素除以2

打印结果:

array([[0.5, 1. , 1.5, 2. , 2.5],
       [3. , 3.5, 4. , 4.5, 5. ]])

执行程序3:

import numpy as np
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
arr * 3 # 所有元素乘3

打印结果:

array([[ 3,  6,  9, 12, 15],
       [18, 21, 24, 27, 30]])

注意:如果是列表*3,则只会分别粘贴复制3次列表中的元素,组成新的列表

数组与数组的运算:(不同形状的数组是不可以在一起运算的)

测试程序:

import numpy as np
arr1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
arr2 = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
arr1 + arr2

测试结果:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-44-18acd144a7ff> in <module>
      2 arr1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
      3 arr2 = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
----> 4 arr1 + arr2

ValueError: operands could not be broadcast together with shapes (2,4) (2,5) 

广播机制:数组在进行矢量运算时,要求数组的形状是相等的。当形状不相等的数组执行算术运算时,就会出现广播机制,该机制会对数组进行扩展,使数组的形状属性值一样。这样,就可以进行矢量化运算。广播机制实现了两个或两个以上数组的运算,即使这些数组的shape不是完全相同的,只要满足一个条件即可:

  • 数组的某一维度等长
  • 其中一个数组的某一个维度是1

执行程序:

import numpy as np
arr1 = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]])
arr2 = np.array([[1], [2]])
print('arr1的形状是:',arr1.shape)
print('arr2的形状是:',arr2.shape)
arr1 + arr2

执行结果:

arr1的形状是: (2, 6)
arr2的形状是: (2, 1)
array([[ 2,  3,  4,  5,  6,  7],
       [ 9, 10, 11, 12, 13, 14]])

广播机制需要扩展维度小的数组,使得它与维度大的数组的shape值相同,以便使用元素级函数或者运算符进行运算。

5.16 矩阵与向量相关

矩阵和数组的区别是矩阵必须是二维的,而数组可以是多维的。矩阵和向量的区别是向量是特殊的矩阵。
矩阵的加法:行和列相等可以进行加法,对应元素进行加和。
标量乘法:矩阵中的每个元素都要一一和标量进行相乘。
矩阵和向量乘法:m * n阶的矩阵和n * 1阶的向量进行相乘,得到m * 1阶的向量
矩阵乘法:m * n矩阵乘以n * o,得到m*n阶矩阵
矩阵乘法的性质:

  • 矩阵乘法不满足交换律:AxB不等于BxA
  • 矩阵乘法满足结合律:(AxB)xC=Ax(BxC)
  • 单位矩阵:主对角线上的元素都是1,其它元素都是0,这种矩阵是单位矩阵

矩阵的逆:如矩阵是一个m*m矩阵(方阵),如果有逆矩阵,则AA-1=A-1A。低阶矩阵球逆的方法是待定系数法和初等变换
矩阵的转置:矩阵的行转置后变成矩阵的列,矩阵的列变成矩阵的行。
矩阵的运算:矩阵的运算可以使用在大学求最终成绩上,很多位学生(决定矩阵的行数)的平时成绩和期末成绩组成n行2列的矩阵,再乘以0.7和0.3组成的2行1列的矩阵,得到n行1列的矩阵就是每位学生的最终成绩。在numpy库中矩阵乘法使用到matmul和dot函数:两者相同点是都可以做矩阵之间的乘法,不同点是matmul不支持矩阵与标量的乘法,而dot支持

测试两者都可以做矩阵之间的乘法

# 测试dot和matmul函数都可以做矩阵之间的乘法
import numpy as np
a = np.array([[89, 90], [88, 89], [87, 78]])
b = np.array([0.7, 0.3])
arr1 = np.matmul(a, b)
print(arr1)
arr2 = np.dot(a, b)
print(arr2)

测试结果:

[89.3 88.3 84.3]
[89.3 88.3 84.3]

测试只有dot函数支持矩阵与标量的乘法:

# 测试只有dot函数支持矩阵与标量的乘法
import numpy as np
a = np.array([[89, 90], [88, 89], [87, 78]])
arr1= np.dot(2,a)
print(arr1)
arr2= np.matmul(2, a)
[[178 180]
 [176 178]
 [174 156]]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-59-653e8ec1b561> in <module>
      4 arr1= np.dot(2,a)
      5 print(arr1)
----> 6 arr2= np.matmul(2, a)

ValueError: matmul: Input operand 0 does not have enough dimensions (has 0, gufunc core with signature (n?,k),(k,m?)->(n?,m?) requires 1)
6. Pandas
6.1 Pandas介绍

Pandas由WesMcKinney开发,是一种专门用于数据挖掘的库。其以Numpy库为基础,借力Numpy模块在计算方面性能高的优势来增强性能。也基于matplotlib库,能够简便绘图,并且有着独特的数据结构。

6.2 使用Pandas的优势

Numpy已近可以帮助我们解决问题,能够结合Matplotlib解决部分数据的展示等问题,那为什么要使用Pandas,使用它的优势主要有以下几个部分:

  • 增强图表的可读性
  • 便捷的数据处理能力
  • 读取文件特别方便
  • 封装了Matplotlib的画图和Numpy的计算
6.3 Pandas数据结构

Pandas一共有三种数据结构,分别是Series、DataFrame和MultiIndex。三者分别是一维数据结构、二维数据结构和三维数据结构

➢ Series结构

Series是一个类似于一维数组结构,它能够保存任何数据类型的数据,如整数、字符串、浮点数等,主要由一组数据和与之相关联的数组两部分组成

Series的创建(通过已有数据创建):

import pandas as pd
# data:传入的数据,可以是ndarray、list等
# index:索引,必须是唯一且与数据的长度相等,如果没有传入索引参数,则默认会自动创建一个从0~N的整数索引
# dtype:数据类型
pd.Series(data=None, index=None, dtype=None)
  • 指定内容默认索引创建
import pandas as pd
import numpy as np
pd.Series(data=np.arange(10))

在这里插入图片描述

  • 指定索引创建
import pandas as pd
pd.Series(data=[6, 7, 8, 9, 10], index=[0, 1, 2, 3, 4])

在这里插入图片描述

  • 通过字典数据创建
import pandas as pd
pd.Series(data={'name': 'thanlon', 'age': 24, 'address': '中国上海'})

在这里插入图片描述
为更方便地操作Series对象中的索引和数据,Series中提供两个属性,分别是index和values。Series的属性:

  • index
import pandas as pd
staff = pd.Series(data={'name': 'thanlon', 'age': 24, 'address': '中国上海'})
print('职员的姓名:',staff[0])
print('职员的年龄:',staff['age'])
print(staff.index)

在这里插入图片描述

  • values
import pandas as pd
staff = pd.Series(data={'name': 'thanlon', 'age': 24, 'address': '中国上海'})
print(staff.values) # <class 'numpy.ndarray'>

在这里插入图片描述
➢ DataFrame结构:

DataFrame是一个类似于二维数组或表格的对象,既有行索引和列索引。DataFrame的创建:

import pandas as pd
# index:行标签,如果没有传入索引参数,则默认会自动创建一个从0~N的整数索引
# columns:列标签,如果没有传入索引参数,则默认会自动创建一个从0~N的整数索引
pd.DataFrame(data=None, index=None, columns=None)

例一:

import pandas as pd
import numpy as np
pd.DataFrame(data=np.random.randn(2, 3))

在这里插入图片描述
例二:

# 分别使用numpy和pandas生成学生的成绩表,生成10个同学的6个科目的成绩
import numpy as np
score = np.random.randint(0, 100, (10, 6))
print(score)
score_df = pd.DataFrame(score)
score_df

在这里插入图片描述
增加行列索引:

import numpy as np
import pandas as pd
score = np.random.randint(60, 100, (9, 6))
print(score)
score_df = pd.DataFrame(score)
print(score_df)
# 构建行索引序列
subjects = ['语文', '数学', '英语', '历史', '政治', '数学']
# 构建列索引序列
stu = ['学生'+str(i+1) for i in range(score_df.shape[0])]
# 添加行索引
data = pd.DataFrame(data=score,  index=stu, columns=subjects)
data

在这里插入图片描述
DataFrame的属性:

  • shape:查看几行几列
'''
查看几行几列
'''
import numpy as np
import pandas as pd
score = np.random.randint(60, 100, (9, 6))
score_df = pd.DataFrame(score)
subjects = ['语文', '数学', '英语', '历史', '政治', '数学']
stu = ['学生'+str(i+1) for i in range(score_df.shape[0])]
data = pd.DataFrame(data=score,  index=stu, columns=subjects)
print(data.shape)
data

在这里插入图片描述

  • index:获取行索引列表
'''
获取行索引列表
'''
import numpy as np
import pandas as pd
score = np.random.randint(60, 100, (9, 6))
score_df = pd.DataFrame(score)
subjects = ['语文', '数学', '英语', '历史', '政治', '数学']
stu = ['学生'+str(i+1) for i in range(score_df.shape[0])]
data = pd.DataFrame(data=score,  index=stu, columns=subjects)
print(data.index)
data

在这里插入图片描述

  • columns:获取列索引列表
'''
获取列索引列表
'''
import numpy as np
import pandas as pd
score = np.random.randint(60, 100, (9, 6))
score_df = pd.DataFrame(score)
subjects = ['语文', '数学', '英语', '历史', '政治', '数学']
stu = ['学生'+str(i+1) for i in range(score_df.shape[0])]
data = pd.DataFrame(data=score,  index=stu, columns=subjects)
print(data.columns)
data

在这里插入图片描述

  • values:获取数组的值
'''
获取数组的值
'''
import numpy as np
import pandas as pd
score = np.random.randint(60, 100, (9, 6))
score_df = pd.DataFrame(score)
subjects = ['语文', '数学', '英语', '历史', '政治', '数学']
stu = ['学生'+str(i+1) for i in range(score_df.shape[0])]
data = pd.DataFrame(data=score,  index=stu, columns=subjects)
print(data.values)
data

在这里插入图片描述

  • T:转置
import numpy as np
import pandas as pd
score = np.random.randint(60, 100, (9, 6))
score_df = pd.DataFrame(score)
subjects = ['语文', '数学', '英语', '历史', '政治', '数学']
stu = ['学生'+str(i+1) for i in range(score_df.shape[0])]
data = pd.DataFrame(data=score,  index=stu, columns=subjects)
data.T

在这里插入图片描述

  • head(n):查看前n行,如果不传入n,默认是5行。如果数据没有5行,则默认查看所有行。
import numpy as np
import pandas as pd
score = np.random.randint(60, 100, (9, 6))
score_df = pd.DataFrame(score)
subjects = ['语文', '数学', '英语', '历史', '政治', '数学']
stu = ['学生'+str(i+1) for i in range(score_df.shape[0])]
data = pd.DataFrame(data=score,  index=stu, columns=subjects)
data.head(4)

在这里插入图片描述

  • tail(n):查看后n行,如果不传入n,默认是5行。如果数据没有5行,则默认查看所有行。
import numpy as np
import pandas as pd
score = np.random.randint(60, 100, (9, 6))
score_df = pd.DataFrame(score)
subjects = ['语文', '数学', '英语', '历史', '政治', '数学']
stu = ['学生'+str(i+1) for i in range(score_df.shape[0])]
data = pd.DataFrame(data=score,  index=stu, columns=subjects)
data.tail(2)

在这里插入图片描述
DataFrame索引的设置:

  • 修改行列索引值
'''
必须整体全部修改,不能使用索引方式改局部,如data.index[0] = '学生_1'
'''
import numpy as np
import pandas as pd
score = np.random.randint(60, 100, (9, 6))
score_df = pd.DataFrame(score)
subjects = ['语文', '数学', '英语', '历史', '政治', '数学']
stu = ['学生'+str(i+1) for i in range(score_df.shape[0])]
data = pd.DataFrame(data=score,  index=stu, columns=subjects)
stu1 = ['学生_'+str(i+1) for i in range(score_df.shape[0])]
data.index = stu1
data

在这里插入图片描述

  • 重设索引
'''
使用reset_index(drop=False),可以用来设置新的下标索引,drop:默认是False,不删除原来的索引,如果为True,删除原来的索引值
不删除原来的索引
'''
import numpy as np
import pandas as pd
score = np.random.randint(60, 100, (9, 6))
score_df = pd.DataFrame(score)
subjects = ['语文', '数学', '英语', '历史', '政治', '数学']
stu = ['学生'+str(i+1) for i in range(score_df.shape[0])]
data = pd.DataFrame(data=score,  index=stu, columns=subjects)
data = data.reset_index()
data

在这里插入图片描述

'''
使用reset_index(drop=False),可以用来设置新的下标索引,drop:默认是False,不删除原来的索引,如果为True,删除原来的索引值
删除原来的索引
'''
import numpy as np
import pandas as pd
score = np.random.randint(60, 100, (9, 6))
score_df = pd.DataFrame(score)
subjects = ['语文', '数学', '英语', '历史', '政治', '数学']
stu = ['学生'+str(i+1) for i in range(score_df.shape[0])]
data = pd.DataFrame(data=score,  index=stu, columns=subjects)
data = data.reset_index(drop=True)
data

在这里插入图片描述

  • 以某列值设置为新的索引
'''
设置新的索引:set_index(keys, drop=True)
keys:列索引名称或列索引名称的列表
drop:boolean类型,默认是True,当做新的索引,删除原来的列
以月份设置新的索引
'''
import pandas as pd
df = pd.DataFrame({
    'month': [1, 2, 3, 4],
    'year': [2017,2018, 2019, 2020],
    'sale': [66, 77, 88, 99]
})
df = df.set_index('month') # 设置单个索引
df

在这里插入图片描述

'''
设置新的索引:set_index(keys, drop=True)
keys:列索引名称或列索引名称的列表
drop:boolean类型,默认是True,当做新的索引,删除原来的列
以年份和月份设置新的索引
'''
import pandas as pd
df = pd.DataFrame({
    'month': [1, 2, 3, 4],
    'year': [2017, 2018, 2019, 2020],
    'sale': [66, 77, 88, 99]
})
df = df.set_index(['year', 'month']) # 设置多个索引,要使用列表
df

在这里插入图片描述

DataFrame通过修改可以变成MultiIndex结构。

➢ MultiIndex结构

MultiIndex是三维的数据结构,即多级索引,也称为层次化的索引。层次化索引是pandas的重要功能,可以在Series、DataFrame对象上拥有2个及其以上的索引。除了通过修改DataFrame数据结构变成MulitiIndex结构,还可以直接创建。

MultiIndex的创建:

import pandas as pd
arrays = [['thanlon', 'kiku', 'kili'], [22, 23, 24]]
pd.MultiIndex.from_arrays(arrays=arrays, names=('name', 'age'))

在这里插入图片描述
MultiIndex的特性:

'''
index
'''
import pandas as pd
df = pd.DataFrame({
    'month': [1, 2, 3, 4],
    'year': [2017, 2018, 2019, 2020],
    'sale': [66, 77, 88, 99]
})
df = df.set_index(['year', 'month'])
df.index

在这里插入图片描述

'''
index.names
'''
import pandas as pd
df = pd.DataFrame({
    'month': [1, 2, 3, 4],
    'year': [2017, 2018, 2019, 2020],
    'sale': [66, 77, 88, 99]
})
df = df.set_index(['year', 'month'])
df.index.names

在这里插入图片描述

import pandas as pd
df = pd.DataFrame({
    'month': [1, 2, 3, 4],
    'year': [2017, 2018, 2019, 2020],
    'sale': [66, 77, 88, 99]
})
df = df.set_index(['year', 'month'])
df.index.levels

在这里插入图片描述

import pandas as pd
df = pd.DataFrame({
    'month': [1, 2, 3, 4],
    'year': [2017, 2018, 2019, 2020],
    'sale': [66, 77, 88, 99]
})
df = df.set_index(['year', 'month'])
df.index.codes

在这里插入图片描述
➢ Panel结构(Panel已被废弃,这里只作了解)

Panel是MultiIndex的前身,Panel的创建:

'''
pandas.Panel(data-None, items=None, major_axis=None, minor_axis=None):存储3维数组的Panel结构
data:ndarray或者DataFrame,表示整体的数据
items:索引或类似数组的对象,axis=0
major_axis:索引或类似数组的对象,axis=1
minor_axis:索引或类似数组的对象,axis=2
'''
import pandas as pd
import numpy as np
# 24个数,第一个维度是4,第二个维度是3,第三个维度是2,三维
data = np.arange(24).reshape(4, 3, 2)
items = list('ABCD')  # ['A', 'B', 'C', 'D']
major_axis = pd.date_range('20200227', periods=3) # DatetimeIndex(['2020-02-27', '2020-02-28', '2020-02-29'], dtype='datetime64[ns]', freq='D')
minor_axis = ['first', 'second']
pd.Panel(data=data, items=items, major_axis=major_axis, minor_axis=minor_axis)

在这里插入图片描述
Panel数据的查看:

 import pandas as pd
import numpy as np
# 24个数,第一个维度是4,第二个维度是3,第三个维度是2,三维
data = np.arange(24).reshape(4, 3, 2)
items = list('ABCD')  # ['A', 'B', 'C', 'D']
major_axis = pd.date_range('20200227', periods=3) # DatetimeIndex(['2020-02-27', '2020-02-28', '2020-02-29'], dtype='datetime64[ns]', freq='D')
minor_axis = ['first', 'second']
p = pd.Panel(data=data, items=items,
             major_axis=major_axis, minor_axis=minor_axis)
p[:, :, 'first']  # :表示取所有
p['A', :, :]
6.4 基本数据操作

➢ 索引操作

直接使用行列索引(先行后列):

结合loc或者iloc使用索引:

使用ix组合索引:

6.5 DataFrame运算
6.6 Pandas绘图

➢ Pandas.Series绘图

绘制折线图:

import pandas as pd
import numpy as np
import random
data = []
for i in np.arange(0, 100, 10):
    data.append(random.randint(10, 20))
s = pd.Series(data=data)
print(s)
s.plot(kind='line')  # s.plot.line(),s.plot()函数的参数kind默认是'line'

在这里插入图片描述
绘制柱状图:

import pandas as pd
import numpy as np
import random
data = []
for i in np.arange(0, 100, 10):
    data.append(random.randint(10, 20))
s = pd.Series(data=data)
print(s)
s.plot(kind='bar')

在这里插入图片描述

import pandas as pd
import numpy as np
import random
data = []
for i in np.arange(0, 100, 10):
    data.append(random.randint(10, 20))
s = pd.Series(data=data)
print(s)
s.plot(kind='barh')

在这里插入图片描述
绘制直方图:

import pandas as pd
import numpy as np
import random
data = []
for i in np.arange(0, 100, 10):
    data.append(random.randint(10, 20))
data = np.random.normal(1.75, 1, 10000) 
s = pd.Series(data=data)
print(s)
s.plot(kind='hist')

在这里插入图片描述
➢ Pandas.DataFrame绘图

绘制折线图:

import pandas as pd
import numpy as np
data = np.random.randn(10, 2)  # 从标准动态分布中返回一个或多个样本值
print(data)
df = pd.DataFrame(data=data)
print(df)
df.plot(kind='line')  # df.plot()函数的参数kind默认是'line'

在这里插入图片描述
绘制柱状图:

import pandas as pd
import numpy as np
data = np.random.randn(10, 3)  # 从标准动态分布中返回一个或多个样本值
print(data)
df = pd.DataFrame(data=data)
print(df)
df.plot(kind='bar')  # df.plot.line(),df.plot()函数的参数kind默认是'line'

在这里插入图片描述

import pandas as pd
import numpy as np
data = np.random.randn(10, 3)  # 从标准动态分布中返回一个或多个样本值
df = pd.DataFrame(data=data)
df.plot(kind='barh')  # df.plot()函数的参数kind默认是'line'

在这里插入图片描述
绘制直方图:

import pandas as pd
import numpy as np
data = np.random.randn(10, 3)  # 从标准动态分布中返回一个或多个样本值
print(data)
df = pd.DataFrame(data=data)
print(df)
df.plot(kind='hist')  # df.plot()函数的参数kind默认是'line'

在这里插入图片描述

6.7 文件读取与存储

➢ CSV格式文件的读取与存储

test.csv:
在这里插入图片描述
CSV格式文件的读取:

'''
读取数据,并且指定只获取age和addr指标
'''
import pandas as pd
pd.read_csv(filepath_or_buffer='test.csv')
# filepath_or_buffer:文件路径;usecols:指定读取的列名;sep:默认是以逗号分割
pd.read_csv(filepath_or_buffer='test.csv', usecols=['name', 'age'], sep=',')

在这里插入图片描述
CSV格式文件的存储:

'''
存储数据
'''
import pandas as pd
data = pd.read_csv(filepath_or_buffer='test.csv',
                   usecols=['name', 'age'], sep=',')
# to_csv的参数,columns:选择需要的列索引;header:是否写进列索引值,默认是True;index:是否写进索引,默认是True。mode:重写(w)与追加(a)
data.to_csv(path_or_buf='tmp.csv', columns=[
            'name'], header=True, index=None, mode='w')
data = pd.read_csv(filepath_or_buffer='tmp.csv')
data

在这里插入图片描述

'''
存储数据,不保存索引
'''
import pandas as pd
data = pd.read_csv(filepath_or_buffer='test.csv', usecols=['name', 'age'], sep=',') # 
data.to_csv(path_or_buf='tmp.csv',columns=['name'],index=False)
data = pd.read_csv(filepath_or_buffer='tmp.csv')
data

在这里插入图片描述
➢ HDF5格式文件的读取与存储

创建HDF5文件:

首先安装h5py模块:thanlon@thanlon-master:~$ sudo pip3 install h5py -i https://pypi.tuna.tsinghua.edu.cn/simple

创建好的HDF5文件:

import h5py
f = h5py.File('hd.h5', 'w')
lst1 = ['thanlon', 'kiku', 'kili']
column_01 = []
for i in lst1:
    column_01.append(i.encode())
f['name'] = column_01
f['age'] = [11,22,23]
print(f.keys())
print(f['name'][:])
print(f['age'][:])
f.close()

HDF5格式文件的读取:

# 安装tables模块,sudo pip3 install tables -i https://pypi.tuna.tsinghua.edu.cn/simple
import pandas as pd
data = pd.read_hdf('hd.h5')
data.head()

HDF5格式文件的存储:

import pandas as pd
data = pd.read_hdf('hd.h5')
data.to_hdf('hd.h5', key='data')  # 注意这里必须有要有key
pd.read_hdf('hd.h5', key='data')

HDF5在存储的时候,使用的方式blosc,这种方式是速度读取快,也是pandas默认支持的。使用压缩提高磁盘利用率节省空间。HDF5还是跨平台的,可以轻松迁移到hadoop上面。

➢ JSON格式文件的读取与存储

JSON格式文件的读取:


JSON格式文件的存储:


7. 综合实例:K线图的绘制
发布了54 篇原创文章 · 获赞 138 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Thanlon/article/details/103781509
今日推荐