Java教程

day05>>>pandas其他操作补充、matplotlib模块

本文主要是介绍day05>>>pandas其他操作补充、matplotlib模块,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

pandas其他操作补充、matplotlib模块

 

缺失值处理

# 语句
1. df.isnull  # 还有df.notnull
2. df.fillna
3. df.dropna

  上述三条语句其实在Series中就已经介绍过了,缺失值的识别与处理主要围绕上述三条语句。今天我们直接通过题目来实操。

  首先导入文件:

data05 = pd.read_excel(r'data_test05.xlsx')
data05  # 读取文件内容

  初步浏览了一下文件内容,发现其中有些数据是缺失的。

  目前只有十条数据,所以仅靠肉眼目测就能应付过来。但如果数据量有成千上万行,那么就需要用代码来帮助实现了。

  首先是判断数据是否有缺失。

data05.isnull()  # 统计每个数据项是否有缺失

  因为统计的是有否缺失,所以缺失数据会返回True。但这样显然无法满足需要,我们可以对它们进行统计。

data05.isnull().sum()# 统计每一列缺失数据的个数

  如果只是为了统计有没有缺失数据,我们还可以使用下面这条语句:

data05.isnull().any(axis = 0)  # 统计列字段下是否含有缺失

  现在知道了那些数据是空缺的,我们就可以进行下一步操作了。

  注意:针对缺失数据,有时候可以删除,有时需要处理保留。当缺失数据量达到一定程度之后就不该删除。

  所以我们要先计算一下缺失数据到底有多少,会不会影响接下来的步骤。

data05.isnull().sum(axis = 0)/data05.shape[0]  # 计算各列数据的缺失比例

  通常情况下,只有当异常数据的占比小于0.1(10%)才可以删除缺失数据。

  所以我们要填充缺失数据,但是填充数据也不是胡来的。

  要点:针对缺失数据的填充不能盲目,要结合具体字段采取不同的填充策略。

data05.fillna(value=0)  # 将所有的缺失值填充为0(不合理)
"""针对不同的缺失值使用合理的填充手段"""
data05.fillna(value = {
  'gender':data05.gender.mode()[0],  # 性别用众数(出现频率最高的数):可以有一个也可能是多个
  'age':data05.age.mean(),  # 年龄用平均值
  'income':data05.income.median()  # 收入用中位数
}, inplace = True)

 

数据汇总

  透视表可以理解为将单个单个的数据按组显示的表格,概念上类似于MySQL的分组。我们通常是在excel中生成透视表的,其实pandas也可以做到。

# 透视表功能
pd.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')

  看的眼睛花了?确实,一条语句里面蕴含了十来个关键字,刚接触任谁都会眼花。所以现在我们一个一个来看这些关键字有什么作用。

data:指定需要构造透视表的数据集 
values:指定需要拉入“数值”框的字段列表
index:指定需要拉入“行标签”框的字段列表 
columns:指定需要拉入“列标签”框的字段列表 
aggfunc:指定数值的统计函数,默认为统计均值,也可以指定numpy模块中的其他统计函数 
fill_value:指定一个标量,用于填充缺失值 
margins:bool类型参数,是否需要显示行或列的总计值,默认为False 
dropna:bool类型参数,是否需要删除整列为缺失的字段,默认为True 
margins_name:指定行或列的总计名称,默认为All

  看起来还是不容易理解,接下来就来一道案例帮助消化。

data06 = pd.read_csv(r'diamonds.csv')
data06.tail()

   查看了一下数据,没问题,那么接下来就可以生成透视表了。

pd.pivot_table(data06, index = 'color', values='price', aggfunc='mean')  # 按color分组,price作为数值,统计平均值

   pandas还支持二次分组:

pd.pivot_table(data06, index = 'color', columns='clarity', values='price', aggfunc='size')  # 按color分组,再以清澈度分组,price作为数值,统计个数

 

分组与聚合

  之前的透视表有些类似分组的概念,现在我们来看看真正的分组和聚合应该怎么做。

grouped = data06.groupby(by = ['color','cut'])  # 通过groupby方法,指定分组变量

  分组之后生成了一个对象,没法直接看到结果。

  分组还只是第一步,接下来还要使用聚合对分组中的数据进行统计。

# 对分组变量进行统计汇总
result = grouped.aggregate({'color':np.size, 'carat':np.min,   # 求颜色的个数,克拉数的最小值
                            'price':np.mean, 'table':np.max})  # 求价钱的平均数,表面积的最大值

  可以看到,计算所用到的关键字都是np点出各种用法,还是印证了那句话——numpy模块是很多科学计算模块的底层模块。

  关于聚合函数还有一些用法,不常用但也十分简单,所以不具体展开讲了,有兴趣自己尝试一下便能很快上手了。

# 调整变量名的顺序
result = pd.DataFrame(result, columns=['color','carat','price','table'])
​
​
# 数据集重命名
result.rename(columns={'color':'counts',
                       'carat':'min_weight',
                       'price':'avg_price',
                       'table':'max_table'}, 
              inplace=True)

 

分组与聚合实战案例

  接下来我们来一道实战题演练一下分组与聚合的用法。

  地址:https://baike.baidu.com/item/NBA%E6%80%BB%E5%86%A0%E5%86%9B/2173192?fr=aladdin

  需求:分析NBA各球队冠军次数及球员FMVP次数。

# 1.首先从网页上爬取数据
res = pd.read_html('https://baike.baidu.com/item/NBA%E6%80%BB%E5%86%A0%E5%86%9B/2173192?fr=aladdin')  # 返回的是一个列表,列表中是当前页面的所有表格数据
res

  现在获取到所有表格数据了,那么下一步就是获取我们需要的数据。

  因为获取到的数据是列表形式的,所以我们只要索引取值就能获得需要的数据了。

# 2.获取有效数据
cp = res[0]
cp

  这样我们需要的数据就找到了,但是仔细看一下好像有些小瑕疵:表头数据被移到了数据的第一行。小问题,做下修改就好了。

cp.rename(columns=cp.iloc[0],inplace=True)
cp.drop(0,inplace=True)
cp

# 针对冠军字段分组
cp.groupby('冠军').groups

  虽然卖相不太好,但至少都能显示出来了。

# 获取分组之后的各分组的夺冠次数
champion.groupby('冠军').size()

# 排序各组冠军次数
cp.groupby('冠军').size().sort_values(ascending=False)  # 升序

# 求筛选出球队和MVP
cp.groupby(['冠军', 'FMVP']).size()  # 分组字段可以一次性取多个

 

数据的合并

pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False, keys=None)

  我们来看一下合并数据的语句中用到的关键字。

objs:指定需要合并的对象,可以是序列、数据框或面板数据构成的列表 
axis:指定数据合并的轴,默认为0,表示合并多个数据的行,如果为1,就表示合并多个数据的列
join:指定合并的方式,默认为outer,表示合并所有数据,如果改为inner,表示合并公共部分的数据 
join_axes:合并数据后,指定保留的数据轴 
ignore_index:bool类型的参数,表示是否忽略原数据集的索引,默认为False,如果设为True,就表示忽略原索引并生成新索引
keys:为合并后的数据添加新索引,用于区分各个数据部分

  再借题目来加深理解。

# 构造数据集df1和df2
df1 = pd.DataFrame({
  'name':['张三','李四','王二'], 
  'age':[21,25,22], 
  'gender':['男','女','男']}
)
df2 = pd.DataFrame({
  'name':['丁一','赵五'], 
  'age':[23,22], 
  'gender':['女','女']}
)

  接下来就是纵向合并的语法了。

# 数据集的纵向合并
pd.concat([df1,df2] , keys = ['df1','df2'])  # 加keys参数可以在合并之后看到数据来源
​
pd.concat([df1,df2] , keys = ['df1','df2']).reset_index()  # reset_index可以重置行索引
​
pd.concat([df1,df2] , keys = ['df1','df2']).reset_index().drop(labels ='level_1', axis = 1).rename(columns = {'level_0':'Class'})

  纵向合并必须满足一个条件:列的名称是一样的。

  如果不一样会发生什么呢?

  这就来演示一下。

# 如果df2数据集中的“姓名变量为Name”
df2 = pd.DataFrame({
  'Name':['丁一','赵五'], 
  'age':[23,22], 
  'gender':['女','女']}
)
# 数据集的纵向合并
pd.concat([df1,df2])

  出现了缺失数据,所以一定要记住:纵向合并时列的名称是一样的。

 

数据的连接

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'))

  该语法会用到的关键字如下:

left:指定需要连接的主 right:指定需要连接的辅表
how:指定连接方式,默认为inner内连,还有其他选项,如左连left、右连right和外连outer on:指定连接两张表的共同字段
left_on:指定主表中需要连接的共同字段
right_on:指定辅表中需要连接的共同字段 
left_index:bool类型参数,是否将主表中的行索引用作表连接的共同字段,默认为False right_index:bool类型参数,是否将辅表中的行索引用作表连接的共同字段,默认为False sort:bool类型参数,是否对连接后的数据按照共同字段排序,默认为False 
suffixes:如果数据连接的结果中存在重叠的变量名,则使用各自的前缀进行区分

  接下来还是以题目来做实验。

  首先还是要准备数据

# 构造数据集
df3 = pd.DataFrame({
  'id':[1,2,3,4,5],
  'name':['张三','李四','王二','丁一','赵五'],
  'age':[27,24,25,23,25],
  'gender':['男','男','男','女','女']})
df4 = pd.DataFrame({
  'Id':[1,2,2,4,4,4,5], 
  'score':[83,81,87,75,86,74,88], 
  'kemu':['科目1','科目1','科目2','科目1','科目2','科目3','科目1']})
df5 = pd.DataFrame({
  'id':[1,3,5],
  'name':['张三','王二','赵五'],
  'income':[13500,18000,15000]})

# 首先df3和df4连接
merge1 = pd.merge(left = df3, 
                  right = df4, 
                  how = 'left', 
                  left_on='id', 
                  right_on='Id')

 

# 再将连接结果与df5连接
merge2 = pd.merge(left = merge1, 
                  right = df5, 
                  how = 'left')

  是不是有似曾相识的感觉?没错这就是MySQL中的联表操作。

 

数据分析三剑客之matplotlib模块

 

简介

  matplotlib模块是一款强大的python绘图和数据可视化工具包,数据可视化也是我们数据分析重要环节之一,可以帮助我们分析出很多价值信息,也是数据分析的最后一个可视化阶段。

 

下载

# python纯开发环境下
pip3 install matplotlib
# anaconda环境下
conda install matplotlib
'''anaconda已经自动帮助我们下载好了数据分析相关的模块,其实无需我们再下载'''

 

导入

import matplotlib.pyplot as plt

  因为这三款模块的常用型,所以数据分析三剑客习惯一起导入:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

 

饼图的绘制

  饼图属于最传统的统计图形之一,几乎随处可见,例如大型公司的屏幕墙、各种年度论坛的演示稿以及各大媒体发布的数据统计报告等。   饼图是将一个圆分割成不同大小的楔(扇)形,而圆中的每一个楔形代表了不同的类别值,通常根据楔形的面积大小来判断类别值的差异。

# 语法
pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, labeldistance=1.1)

  关键字:

x:指定绘图的数据 
explode:指定饼图某些部分的突出显示,即呈现爆炸式
labels:为饼图添加标签说明,类似于图例说明 
colors:指定饼图的填充色 
autopct:自动添加百分比显示,可以采用格式化的方法显示 
pctdistance:设置百分比标签与圆心的距离 
labeldistance:设置各扇形标签(图例)与圆心的距离

  我们来实操一下:

# 导入第三方模块
import matplotlib.pyplot as plt
# 解决中文乱码情况
plt.rcParams['font.sans-serif'] = ['SimHei']
# 构造数据
edu = [0.2515,0.3724,0.3336,0.0368,0.0057]
labels = ['中专','大专','本科','硕士','其他']
explode = [0,0.1,0,0,0]
# 绘制饼图                                                                              plt.axes(aspect='equal')  # 如果python版本较低可能是扁的需要加该代码   
plt.pie(x = edu,  # 绘图数据
        labels=labels,  # 添加教育水平标签
        autopct='%.1f%%',  # 设置百分比的格式,这里保留一位小数
        explode = explode
       )
# 显示图形
plt.show()

 

条形图的绘制

  虽然饼图可以很好地表达离散型变量在各水平上的差异,但其不擅长对比差异不大或水平值过多的离散型变量,因为饼图是通过各扇形面积的大小来比价差异的,面积的比较有时并不直观。   对于条形图而言,对比的是柱形的高低,柱体越高,代表的数值越大,反之亦然。

# 语法
bar(x, height, width=0.8, bottom=None, color=None, edgecolor=None, tick_label=None, label = None, ecolor=None)

  关键字:

x:传递数值序列,指定条形图中x轴上的刻度值 
height:传递数值序列,指定条形图y轴上的高度
width:指定条形图的宽度,默认为0.8 
bottom:用于绘制堆叠条形图 
color:指定条形图的填充色 
edgecolor:指定条形图的边框色 
tick_label:指定条形图的刻度标签 
label:指定条形图的标签,一般用以添加图例

  我们来实操一下:

'''垂直条形图'''
import pandas as pd
# 读入数据
GDP = pd.read_excel(r'Province GDP 2017.xlsx')
​
# 设置绘图风格(不妨使用R语言中的ggplot2风格)
plt.style.use('ggplot')
# 绘制条形图
plt.bar(x = range(GDP.shape[0]), # 指定条形图x轴的刻度值
        height = GDP.GDP, # 指定条形图y轴的数值
        tick_label = GDP.Province, # 指定条形图x轴的刻度标签
        color = 'steelblue', # 指定条形图的填充色
       )
# 添加y轴的标签
plt.ylabel('GDP(万亿)')
# 添加条形图的标题
plt.title('2017年度6个省份GDP分布')
# 为每个条形图添加数值标签
for x,y in enumerate(GDP.GDP):
    plt.text(x,y+0.1,'%s' %round(y,1),ha='center')
# 显示图形    
plt.show()

这篇关于day05>>>pandas其他操作补充、matplotlib模块的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!