0
点赞
收藏
分享

微信扫一扫

python数据分析三剑客-numpy、pandas、matplotlib

前言

什么是数据分析

数据分析是用适当的方法对收集来的大量数据进行分析,帮助人们作出判断,以便采取适当行动。

在这里插入图片描述

数据分析的流程

在这里插入图片描述

conda和jupyter notebook简介

conda和jupyter notebook是数据分析工作中的两个帮手,对我们学习数据分析能提供巨大的便利。如过有不懂的可以去专门了解一下。

1.conda创建环境命令

conda : data science package & environment manager
创建环境:
conda create --name python3 python=3
切换环境:
windows :activate python3
linux/macos : source activate python3

官方地址: https://www.anaconda.com/download/
推荐使用速度较快的清华源:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/

  1. jupyter notebook:一款编程/文档/笔记/展示软件

     启动命令:jupyter notebook

在这里插入图片描述

matplotlib

什么是matplotlib

matplotlib: 最流行的Python底层绘图库,主要做数据可视化图表,名字取材于MATLAB,模仿MATLAB构建

为什么要学习matplotlib

1.能将数据进行可视化,更直观的呈现
2.使数据更加客观、更具说服力
在这里插入图片描述

matplotlib基本要点

在这里插入图片描述
每个红色的点是坐标,把5个点的坐标连接成一条线,组成了一个折线图

那么到底如何把它通过代码画出来呢?

通过下面的小例子我们来看一下matplotlib该如何简单的使用

假设一天中每隔两个小时(range(2,26,2))的气温(℃)分别是[15,13,14.5,17,20,25,26,26,27,22,18,15]

在这里插入图片描述
在这里插入图片描述
我们能看明白这个图是什么,但是别人能看明白么???

目前存在以下几个问题:

  1. 设置图片大小(想要一个高清无码大图)
  2. 保存到本地
  3. 描述信息,比如x轴和y轴表示什么,这个图表示什么
  4. 调整x或者y的刻度的间距
  5. 线条的样式(比如颜色,透明度等)
  6. 标记出特殊的点(比如告诉别人最高点和最低点在哪里)
    给图片添加一个水印(防伪,防止盗用)

设置图片大小

在这里插入图片描述
在这里插入图片描述

调整X或者Y轴上的刻度

在这里插入图片描述

那么问题来了:
如果列表a表示10点到12点的每一分钟的气温,如何绘制折线图观察每分钟气温的变化情况?
a= [random.randint(20,35) for i in range(120)]

在这里插入图片描述
在这里插入图片描述

设置中文显示

为什么无法显示中文:
matplotlib默认不支持中文字符,因为默认的英文字体无法显示汉字
查看linux/mac下面支持的字体:
fc-list 查看支持的字体
fc-list :lang=zh 查看支持的中文(冒号前面有空格)

那么问题来了:如何修改matplotlib的默认字体?
通过matplotlib.rc可以修改,具体方法参见源码(windows/linux)
通过matplotlib 下的font_manager可以解决(windows/linux/mac)
在这里插入图片描述
在这里插入图片描述
那么x轴y轴和当前图形到底表示什么是不是应该明确一下呢?

给图像添加描述信息

在这里插入图片描述
在这里插入图片描述

matplotlib只能绘制折线图么?

对比常用统计图

折线图:以折线的上升或下降来表示统计数量的增减变化的统计图
特点:能够显示数据的变化趋势,反映事物的变化情况。(变化)

在这里插入图片描述
直方图:由一系列高度不等的纵向条纹或线段表示数据分布的情况。
一般用横轴表示数据范围,纵轴表示分布情况。
特点:绘制连续性的数据,展示一组或者多组数据的分布状况(统计)
在这里插入图片描述
条形图:排列在工作表的列或行中的数据可以绘制到条形图中。
特点:绘制连离散的数据,能够一眼看出各个数据的大小,比较数据之间的差别。(统计)
在这里插入图片描述
散点图:用两组数据构成多个坐标点,考察坐标点的分布,判断两变量
之间是否存在某种关联或总结坐标点的分布模式。
特点:判断变量之间是否存在数量关联趋势,展示离群点(分布规律)

在这里插入图片描述
折线图的更多应用场景

  • 呈现公司产品(不同区域)每天活跃用户数
  • 呈现app每天下载数量
  • 呈现产品新功能上线后,用户点击次数随时间的变化
  • 呈现员工每天上下班时间

绘制散点图

案例1

假设通过爬虫你获取到了北京2016年3,10月份每天白天的最高气温(分别位于列表a,b),那么此时如何寻找出气温和随时间(天)变化的某种规律?

a = [11,17,16,11,12,11,12,6,6,7,8,9,12,15,14,17,18,21,16,17,20,14,15,15,15,19,21,22,22,22,23]
b = [26,26,28,19,21,17,16,19,18,20,20,19,22,23,17,20,21,20,22,15,11,15,5,13,17,10,11,13,12,13,6]
在这里插入图片描述
技术要点:plt.scatter(x,y)

案例二

假设你获取到了2017年内地电影票房前20的电影(列表a)和电影票房数据(列表b),那么如何更加直观的展示该数据?

a = [“战狼2”,“速度与激情8”,“功夫瑜伽”,“西游伏妖篇”,“变形金刚5:最后的骑士”,“摔跤吧!爸爸”,“加勒比海盗5:死无对证”,“金刚:骷髅岛”,“极限特工:终极回归”,“生化危机6:终章”,“乘风破浪”,“神偷奶爸3”,“智取威虎山”,“大闹天竺”,“金刚狼3:殊死一战”,“蜘蛛侠:英雄归来”,“悟空传”,“银河护卫队2”,“情圣”,“新木乃伊”,]

b=[56.01,26.94,17.53,16.49,15.45,12.96,11.8,11.61,11.28,11.12,10.49,10.3,8.75,7.55,7.32,6.99,6.88,6.86,6.58,6.23] 单位:亿

在这里插入图片描述
在这里插入图片描述

案例三

假设你知道了列表a中电影分别在2017-09-14(b_14), 2017-09-15(b_15), 2017-09-16(b_16)三天的票房,为了展示列表中电影本身的票房以及同其他电影的数据对比情况,应该如何更加直观的呈现该数据?

a = [“猩球崛起3:终极之战”,“敦刻尔克”,“蜘蛛侠:英雄归来”,“战狼2”]
b_16 = [15746,312,4497,319]
b_15 = [12357,156,2045,168]
b_14 = [2358,399,2358,362]

在这里插入图片描述
在这里插入图片描述

绘制直方图

案例一

假设你获取了250部电影的时长(列表a中),希望统计出这些电影时长的分布状态(比如时长为100分钟到120分钟电影的数量,出现的频率)等信息,你应该如何呈现这些数据?

案例二

在美国2004年人口普查发现有124 million的人在离家相对较远的地方工作。根据他们从家到上班地点所需要的时间,通过抽样统计(最后一列)出了下表的数据,这些数据能够绘制成直方图么?

在这里插入图片描述
前面的问题问的是什么呢?
问的是:哪些数据能够绘制直方图

前面的问题中给出的数据都是统计之后的数据,
所以为了达到直方图的效果,需要绘制条形图

所以:一般来说能够使用plt.hist方法的的是那些没有统计过的数据

直方图更多应用场景

  • 用户的年龄分布状态
  • 一段时间内用户点击次数的分布状态
  • 用户活跃时间的分布状态

numpy

什么是numpy

一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算

numpy基础

numpy创建数组(矩阵)

在这里插入图片描述

numpy中常见的更多数据类型

在这里插入图片描述

数据类型的操作

在这里插入图片描述

数组的形状

在这里插入图片描述
在这里插入图片描述

数组和数的计算

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

广播原则

在这里插入图片描述
怎么理解呢?
可以把维度指的是shape所对应的数字个数
那么问题来了:
shape为(3,3,3)的数组能够和(3,2)的数组进行计算么?
shape为(3,3,2)的数组能够和(3,2)的数组进行计算么?
有什么好处呢?
举个例子:每列的数据减去列的平均值的结果

轴(axis)

在numpy中可以理解为方向,使用0,1,2…数字表示,对于一个一维数组,只有一个0轴,对于2维数组(shape(2,2)),有0轴和1轴,对于三维数组(shape(2,2, 3)),有0,1,2轴

有了轴的概念之后,我们计算会更加方便,比如计算一个2维数组的平均值,必须指定是计算哪个方向上面的数字的平均值

那么问题来了:
在前面的知识,轴在哪里?
回顾np.arange(0,10).reshape((2,5)),reshpe中2表示0轴长度(包含数据的条数)为2,1轴长度为5,2X5一共10个数据

二维数组的轴

在这里插入图片描述

三维数组的轴

在这里插入图片描述

numpy读取数据

CSV:Comma-Separated Value,逗号分隔值文件
显示:表格状态
源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录

由于csv便于展示,读取和写入,所以很多地方也是用csv的格式存储和传输中小型的数据,为了方便教学,我们会经常操作csv格式的文件,但是操作数据库中的数据也是很容易的实现的

np.loadtxt(fname,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)

在这里插入图片描述
在这里插入图片描述

numpy中的转置

转置是一种变换,对于numpy中的数组来说,就是在对角线方向交换数据,目的也是为了更方便的去处理数据
在这里插入图片描述
在这里插入图片描述
以上的三种方法都可以实现二维数组的转置的效果,大家能够看出来,转置和交换轴的效果一样

numpy索引和切片

对于刚刚加载出来的数据,我如果只想选择其中的某一列(行)我们应该怎么做呢?
其实操作很简单,和python中列表的操作一样
在这里插入图片描述
在这里插入图片描述

numpy中数值的修改

在这里插入图片描述

numpy中布尔索引

在这里插入图片描述

numpy中三元运算符

在这里插入图片描述

numpy中的clip(裁剪)

在这里插入图片描述

numpy中的nan和inf

nan(NAN,Nan):not a number表示不是一个数字

什么时候numpy中会出现nan:
当我们读取本地的文件为float的时候,如果有缺失,就会出现nan
当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大)

inf(-inf,inf):infinity,inf表示正无穷,-inf表示负无穷

什么时候回出现inf包括(-inf,+inf)
比如一个数字除以0,(python中直接会报错,numpy中是一个inf或者-inf)
在这里插入图片描述

numpy中的nan的注意点

在这里插入图片描述

numpy中的nan的注意点

那么问题来了,在一组数据中单纯的把nan替换为0,合适么?会带来什么样的影响?

比如,全部替换为0后,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以更一般的方式是把缺失的数值替换为均值(中值)或者是直接删除有缺失值的一行

那么问题来了:
如何计算一组数据的中值或者是均值
如何删除有缺失数据的那一行(列)[在pandas中介绍]

numpy中常用统计函数

求和:t.sum(axis=None)
均值:t.mean(a,axis=None) 受离群点的影响较大
中值:np.median(t,axis=None)
最大值:t.max(axis=None)
最小值:t.min(axis=None)
极值:np.ptp(t,axis=None) 即最大值和最小值只差
标准差:t.std(axis=None)在这里插入图片描述
标准差是一组数据平均值分散程度的一种度量。一个较大的标准差,代表大部分数值和其平均值之间差异较大;一个较小的标准差,代表这些数值较接近平均值
反映出数据的波动稳定情况,越大表示波动越大,约不稳定

默认返回多维数组的全部的统计结果,如果指定axis则返回一个当前轴上的结果

ndarry缺失值填充均值

t中存在nan值,如何操作把其中的nan填充为每一列的均值
t = array([[ 0., 1., 2., 3., 4., 5.],
[ 6., 7., nan, 9., 10., 11.],
[ 12., 13., 14., nan, 16., 17.],
[ 18., 19., 20., 21., 22., 23.]])
在这里插入图片描述

数组的拼接

在这里插入图片描述

数组的行列交换

数组水平或者竖直拼接很简单,但是拼接之前应该注意什么?
竖直拼接的时候:每一列代表的意义相同!!!否则牛头不对马嘴

如果每一列的意义不同,这个时候应该交换某一组的数的列,让其和另外一类相同

那么问题来了?
如何交换某个数组的行或者列呢?

数组的行列交换

在这里插入图片描述

numpy更多好用的方法

获取最大值最小值的位置
np.argmax(t,axis=0)
np.argmin(t,axis=1)
创建一个全0的数组: np.zeros((3,4))
创建一个全1的数组:np.ones((3,4))
创建一个对角线为1的正方形数组(方阵):np.eye(3)

numpy生成随机数

在这里插入图片描述

分布的补充

1.均匀分布

在这里插入图片描述
在相同的大小范围内的出现概率是等可能的

2.正态分布

在这里插入图片描述
呈钟型,两头低,中间高,左右对称

numpy的注意点copy和view

  1. a=b 完全不复制,a和b相互影响
  2. a = b[:],视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,他们两个的数据变化是一致的,
  3. a = b.copy(),复制,a和b互不影响

pandas

什么是pandas

pandas is an open source, BSD-licensed library providing high-performance, easy-to-use data structures and data analysis tools for the Python programming language.

为什么要学习pandas

那么问题来了:numpy已经能够帮助我们处理数据,能够结合matplotlib解决我们数据分析的问题,那么pandas学习的目的在什么地方呢?

numpy能够帮我们处理处理数值型数据,但是这还不够
很多时候,我们的数据除了数值之外,还有字符串,还有时间序列等
比如:我们通过爬虫获取到了存储在数据库中的数据
比如:之前youtube的例子中除了数值之外还有国家的信息,视频的分类(tag)信息,标题信息等

所以,numpy能够帮助我们处理数值,但是pandas除了处理数值之外(基于numpy),还能够帮助我们处理其他类型的数据

pandas的常用数据类型

1.Series 一维,带标签数组
2. DataFrame 二维,Series容器

pandas之Series创建

在这里插入图片描述
在这里插入图片描述

pandas之Series切片和索引

在这里插入图片描述
在这里插入图片描述
对于一个陌生的series类型,我们如何知道他的索引和具体的值呢?
在这里插入图片描述

pandas之读取外部数据

现在假设我们有一个组关于狗的名字的统计数据,那么为了观察这组数据的情况,我们应该怎么做呢?

在这里插入图片描述
我们的这组数据存在csv中,我们直接使用pd. read_csv即可

和我们想象的有些差别,我们以为他会是一个Series类型,但是他是一个DataFrame,那么接下来我们就来了解这种数据类型

但是,还有一个问题:
对于数据库比如mysql或者mongodb中数据我们如何使用呢?

pd.read_sql(sql_sentence,connection)

pandas之DataFrame

在这里插入图片描述
DataFrame对象既有行索引,又有列索引
行索引,表明不同行,横向索引,叫index,0轴,axis=0
列索引,表名不同列,纵向索引,叫columns,1轴,axis=1
在这里插入图片描述
在这里插入图片描述
那么问题来了:

  1. DataFrame和Series有什么关系呢?

  2. Series能够传入字典,那么DataFrame能够传入字典作为数据么?那么mongodb的数据是不是也可以这样传入呢?

  3. 对于一个dataframe类型,既有行索引,又有列索引,我们能够对他做什么操作呢

和一个ndarray一样,我们通过shape,ndim,dtype了解这个ndarray的基本信息,那么对于DataFrame我们有什么方法了解呢
在这里插入图片描述

pandas之loc

还有更多的经过pandas优化过的选择方式:

  1. df.loc 通过标签索引行数据
  2. df.iloc 通过位置获取行数据
    在这里插入图片描述
    在这里插入图片描述
    赋值更改数据的过程:
    在这里插入图片描述

pandas之布尔索引

回到之前狗的名字的问题上,假如我们想找到所有的使用次数超过800的狗的名字,应该怎么选择?

在这里插入图片描述
回到之前狗的名字的问题上,假如我们想找到所有的使用次数超过700并且名字的字符串的长度大于4的狗的名字,应该怎么选择?
在这里插入图片描述

pandas之字符串方法

在这里插入图片描述

缺失数据的处理

观察下面这组数据
在这里插入图片描述
我们的数据缺失通常有两种情况:
一种就是空,None等,在pandas是NaN(和np.nan一样)
另一种是我们让其为0,蓝色框中

对于NaN的数据,在numpy中我们是如何处理的?
在pandas中我们处理起来非常容易

判断数据是否为NaN:pd.isnull(df),pd.notnull(df)

处理方式1:删除NaN所在的行列dropna (axis=0, how=‘any’, inplace=False)
处理方式2:填充数据,t.fillna(t.mean()),t.fiallna(t.median()),t.fillna(0)

处理为0的数据:t[t==0]=np.nan
当然并不是每次为0的数据都需要处理
计算平均值等情况,nan是不参与计算的,但是0会

pandas常用统计方法

假设现在我们有一组从2006年到2016年1000部最流行的电影数据,我们想知道这些电影数据中评分的平均分,导演的人数等信息,我们应该怎么获取?
在这里插入图片描述
对于这一组电影数据,如果我们希望统计电影分类(genre)的情况,应该如何处理数据?

思路:重新构造一个全为0的数组,列名为分类,如果某一条数据中分类出现过,就让0变为1
在这里插入图片描述

数据合并之join

join:默认情况下他是把行索引相同的数据合并到一起
在这里插入图片描述
merge:按照指定的列把数据按照一定的方式合并到一起
在这里插入图片描述
默认的合并方式inner,并集
merge outer,交集,NaN补全
merge left,左边为准,NaN补全
merge right,右边为准,NaN补全

分组和聚合

在pandas中类似的分组的操作我们有很简单的方式来完成

df.groupby(by=“columns_name”)

那么问题来了,调用groupby方法之后返回的是什么内容?

grouped = df.groupby(by=“columns_name”)
grouped是一个DataFrameGroupBy对象,是可迭代的
grouped中的每一个元素是一个元组
元组里面是(索引(分组的值),分组之后的DataFrame)

那么,回到之前的问题:
要统计美国和中国的星巴克的数量,我们应该怎么做?
分组之后的每个DataFrame的长度?

长度是一个思路,但是我们有更多的方法(聚合方法)来解决这个问题

在这里插入图片描述

如果我们需要对国家和省份进行分组统计,应该怎么操作呢?

grouped = df.groupby(by=[df[“Country”],df[“State/Province”]])

很多时候我们只希望对获取分组之后的某一部分数据,或者说我们只希望对某几列数据进行分组,这个时候我们应该怎么办呢?

获取分组之后的某一部分数据:
df.groupby(by=[“Country”,“State/Province”])[“Country”].count()

对某几列数据进行分组:
df[“Country”].groupby(by=[df[“Country”],df[“State/Province”]]).count()

观察结果,由于只选择了一列数据,所以结果是一个Series类型
如果我想返回一个DataFrame类型呢?

t1 = df[[“Country”]].groupby(by=[df[“Country”],df[“State/Province”]]).count()t2 = df.groupby(by=[“Country”,“State/Province”])[[“Country”]].count()

以上的两条命令结果一样
和之前的结果的区别在于当前返回的是一个DataFrame类型

那么问题来了:
和之前使用一个分组条件相比,当前的返回结果的前两列是什么?

索引和复合索引

简单的索引操作:

  • 获取index:df.index
  • 指定index :df.index = [‘x’,‘y’]
  • 重新设置index : df.reindex(list(“abcedf”))
  • 指定某一列作为index :df.set_index(“Country”,drop=False)
  • 返回index的唯一值:df.set_index(“Country”).index.unique()

假设a为一个DataFrame,那么当a.set_index([“c”,“d”])即设置两个索引的时候是什么样子的结果呢?

a = pd.DataFrame({‘a’: range(7),‘b’: range(7, 0, -1),‘c’: [‘one’,‘one’,‘one’,‘two’,‘two’,‘two’, ‘two’],‘d’: list(“hjklmno”)})

Series复合索引

在这里插入图片描述
我只想取索引h对应值怎么办?
在这里插入图片描述

DataFrame复合索引

在这里插入图片描述

为什么要学习pandas中的时间序列

不管在什么行业,时间序列都是一种非常重要的数据形式,很多统计数据以及数据的规律也都和时间序列有着非常重要的联系

而且在pandas中处理时间序列是非常简单的

生成一段时间范围

pd.date_range(start=None, end=None, periods=None, freq=‘D’)

start和end以及freq配合能够生成start和end范围内以频率freq的一组时间索引
start和periods以及freq配合能够生成从start开始的频率为freq的periods个时间索引
在这里插入图片描述

关于频率的更多缩写

在这里插入图片描述

在DataFrame中使用时间序列

index=pd.date_range(“20170101”,periods=10)
df = pd.DataFrame(np.random.rand(10),index=index)

回到最开始的911数据的案例中,我们可以使用pandas提供的方法把时间字符串转化为时间序列

df[“timeStamp”] = pd.to_datetime(df[“timeStamp”],format=“”)

format参数大部分情况下可以不用写,但是对于pandas无法格式化的时间字符串,我们可以使用该参数,比如包含中文

那么问题来了:
我们现在要统计每个月或者每个季度的次数怎么办呢?

pandas重采样

重采样:指的是将时间序列从一个频率转化为另一个频率进行处理的过程,将高频率数据转化为低频率数据为降采样,低频率转化为高频率为升采样

pandas提供了一个resample的方法来帮助我们实现频率转化

在这里插入图片描述

PeriodIndex

之前所学习的DatetimeIndex可以理解为时间戳
那么现在我们要学习的PeriodIndex可以理解为时间段

periods = pd.PeriodIndex(year=data[“year”],month=data[“month”],day=data[“day”],hour=data[“hour”],freq=“H”)

那么如果给这个时间段降采样呢?data = df.set_index(periods).resample(“10D”).mean()

举报

相关推荐

0 条评论