• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
草卆鱼
博客园    首页    新随笔    联系   管理    订阅  订阅

10/18

今日考题
1.谈谈缺失数据的概念以及处理缺失数据的方法有哪些

丢失数据出现在重新创建索引或者是两个Series进行运算的情况下 
有索引没有固定的数据则会出现 NaN 即数据缺失
NaN是一个浮点型数据 不太常用的方法可以直接dropna去删除这一数据
或者是通过fillna()  或者在运算中通过fill_value() 去直接填充所需要的值

2.pandas两大数据结构是什么,各自有何特征,如何创建

Series 和 DataFrame
# Series
pd.Series([1,2,3],index=['a','b','c'])
pd.Series({"a":1,"b":2})
它可以视作一个带索引的一维数组(数组概念建议移步numpy模块)
# DataFrame
pd.DataFrame({'one':[1,2,3,4],'two':[4,3,2,1]})
pd.DataFrame({'one':pd.Series([1,2,3],index=['a','b','c']),'two':pd.Series([1,2,3],index=['b','a','c'])})
它可以看成是多个Series的组合 同时携带表头

3.pandas如何读取外部数据

pd.read_csv()  # 读取文本文件和.csv(苹果的表格文件)文件数据
pd.read_html()  # 读页面上table标签内所有的数据 不是table标签读不了
pd.read_excel()  # 读excel表格文件数据
pd.read_sql()  # 读MySQL表格数据
'''每个方法都有自己规定的参数
从上至下参数逐渐减少变的简单'''

4.数据概览常用方法有哪些

mlb.columns  # 查看表头 
mlb.index  	# 查看一行行索引
mlb.shape	# 行列 
mlb.dtypes  	# 数据类型 
mlb.head()  	# 从头取多条数据
mlb.tail()  	# 从末尾取多条数据

复习巩固

  • DataFrame基本介绍
# DF是一种表格型数据结构

#  自定义创建DataFrame的方式
import pandas as pd
pd.DataFrame({'a':[1,2,3],'b':[4,5,6]})
  • 读取外部数据四种方式
"""
1.方法名后面加问号运行查看
2.方法名后面按住shift+tab
"""
1.read_csv()  # 读取文本文件、csv文件数据
	filepath_or_buffer:文件路径
    sep:分隔符
    headers:判断是否含有表头
    names:自定义列字段名词
    encoding:自定义字符编码
    converters:数据类型的转换
    ...
2.read_excel()  # 读取xlsx等excel表格文件
3.read_html()  # 读取HTML页面上table标签内的数据
4.read_sql()  # 读取数据库里面的表格数据(MySQL)
	pymysql模块
    	conn = pymysql.connect(
        	host,port,user,passwd,db,charset
        )	
  • 数据概览
.index  # 查看行标签
.columns  # 查看列字段
.dtyeps  # 查看数据类型
.shape  # 查看行列数
.head  # 查看前面几条数据
.tail  # 查看末尾几条数据
.describe  # 快速统计
  • 数据操作
# 读取列数据
df['列名称']  # df.列名称 改方法有时候会出现关键字冲突的情况
# 如何读取多列
df[['列名称1','列名称2','列名称']]
# 如何创建新的列
df['新列名称'] = 新的列数据  # 既可以是自己指定也可以来自于其他列数据
# 按照指定的条件筛选数据
df.loc[df['Brand'] == '众泰']
df.loc[(df['Brand'] == '众泰') | (df['New_price'] > 10)]
df.loc[df['Brand'] == '众泰',['Brand','Names','New_price']]

内容概要

主体:pandas模块结束,matplotlib模块

  • pandas其他操作补充
  • pandas实战案例
  • 可视化模块matplotlib

详细讲解

缺失值识别和处理

# 遇上缺失值首先想一下那四个有关NaN的方法
1. isnull  # 是NaN为True
2. notnull  # 不是NaN为True
3. dropna  # 丢弃缺失值
4. fillna  # 填充数据
'''简单的四个方法涵盖了数据处理缺失值问题的所有办法了'''
data05 = pd.read_excel(r'data_test05.xlsx')
data05.head()  # 首先导入数据 然后拿前面几行看一下
data05.isnull().any(axis = 0)  # 简单的isnull后面加上any参数 就能查看到列字段下哪些有丢失
data05.isnull().sum(axis = 0)  # 同时还有更好用的sum可以看到缺失几个数据
data05.isnull().sum()/data05.shape[0]  # 拿每列缺失的数据数量除以总行数就知道占比
'''如果数据缺失占比非常小 比如小于1可以考虑直接删除'''

然后就来到缺失处理的关键部分了
这里自然不能用0填充的 字母操作往下看
##############################################################
data05.fillna(value = {
  'gender':data05.gender.mode()[0],  # mode众数哪个多用哪个
  'age':data05.age.mean(),  # meam平均值 年龄不会受极端值影响
  'income':data05.income.median()  # median中位数 真实反映薪资状态
}, inplace = True) #  确认修改
##############################################################
一波操作之后结果如下

数据汇总

# 透视表功能  就是对表进行一些想要的操作比如排序筛选
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.head()

pd.pivot_table(data06, index = 'color', values='price', aggfunc='mean')
pd.pivot_table(data06, index = 'color', columns='clarity', values='price', aggfunc='size')

然后把颜色作为行标签 每个颜色的平均价格作为数据构建透视表
pd.pivot_table(data06, 
               index = 'color', 
               values='price', 
               aggfunc='mean'  # 聚合的关键字aggregate加功能function
              )

分组与聚合

分组非常简单 通过关键字group去控制
# ep:通过color和cut分组  就是先用color分 分完之后color中再通过cut细分
data06.groupby(by = ['color','cut'])  # 由于分组之后只能拿到分组依据这边甚至直接优化不给你看了

想要看到的话就要指定额外的参数
# 先将刚才分好组的数据赋值给一个变量
d6g =  data06.groupby(by = ['color','cut']) 
# 然后通过关键字aggregate 然后再通过numpy的功能筛选出一个个数组中的聚合结果
d6g.aggregate({'color':np.size,'price':np.mean,'table':np.max})

之后也可以调整表头的数据顺序
result = pd.DataFrame(result, columns=['color','carat','price','table'])  # 想要什么顺序就按照什么顺序写入列表

也可以对变换之后的表做重命名
res.rename(columns={'color':'counts',
                       'price':'avg_price',
                       'table':'max_table'})
# 在字典后面加上,inplace = True就能确认修改了

小练习

# 分析NBA各球队冠军次数和球员FMVP次数
champion = pd.read_html('https://baike.baidu.com/item/NBA%E6%80%BB%E5%86%A0%E5%86%9B/2173192?fr=aladdin')[0]  # 通过索引0取到所需的表

然后先做一些简单的处理让表变得合规一些也方便处理
# 先将表头部分替换成表的索引0那行
champion.columns = champion.iloc[0]
# 然后将索引0那行去掉
champion.drop(index = 0 , inplace = True)

做好前期准备之后就可以来进行后续的处理了
# 通过aggregate可以获取分组之后的数据展示
champion.groupby(by='冠军').aggregate({'冠军':np.size})  # size计算数组大小这里就可以看作是count
# 这样就拿到了各个队伍的总冠军数

# 也可以这样进行夺冠计数
champion.groupby('冠军').size()  # 这里size是获取整个表单变成Series了
随后对Series进行排序就简单了
champion.groupby('冠军').size().sort_values(ascending=False)
# 在后面加上.sort_values(ascending=False) 降序排列

# 如果要查看队伍冠军和MVP数量可以把两者直接扔进groupby里面然后size转换
champion.groupby(['冠军', 'FMVP']).size()

也可以通过dataFrame直接改就是会麻烦点
cp = champion.groupby(by='冠军').aggregate({'冠军':np.size})
# 首先把上面得到的DF数据赋值给到变量方便后续操作

#  由于排序一定需要by参数 即通过其中一项数据排序所以要将表头的冠军替换
不然就会出现冲突

# 但是这里很怪重命名的时候又不会选择到前面那个字符
cp.rename(columns={"冠军":"num"},inplace = True)
# 应该是把这个视作行标签的表头  h或者说看作是Series的行标签

之后再通过by来排序就行了
cp.sort_values(by="num",ascending=False)

数据合并

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:为合并后的数据添加新索引,用于区分各个数据部分
# 这个和SQL里面的联表很像 横向合并基本一摸一样

# 数据准备
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参数可以在合并之后看到数据来源  其实并没有啥大用处不加也行

对于刚才那个没什么用的key还有对应的方法.reset_index()
可以重新创建一个和key对应的行标签

这里可以看到level_1里面的行标签还是有些问题的需要调整 
或者可以直接去掉
pd.concat([df1,df2]).reset_index().drop(columns='index')

最后配合上前面可以用key创建索引可以整合成
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.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:如果数据连接的结果中存在重叠的变量名,则使用各自的前缀进行区分
'''程序员都要使用Github所以对merge不会陌生
就是合并 这个合并再Github里面就是合并代码'''

# 首先还是先构造数据集
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]})

然后看一下联表操作是不是真就和SQL里面一摸一样
# 连接df3和df4
mix = pd.merge(left = df3,  # 规定左表
         right = df4, # 规定右表
         how = 'inner', # 连接方式
         left_on='id', # 左表中连接关键字id注意这里是df3自生的id
         right_on='Id')  # 右表中连接关键字Id

之后再将连好的结果和df5连接
pd.merge(left = mix, 
         right = df5, 
         how = 'left')  # 这里有完全对应的字段就不需要再去指定on

matplotlib简介

是一个强大的python绘图和数据可视化工具包,数据可视化也是我们数据分析重要环节之一,可以帮助我们分析出很多价值信息,也是数据分析的最后一个可视化阶段
# python纯开发环境下
pip3 install matplotlib
# anaconda环境下
conda install matplotlib
'''anaconda已经自动帮助我们下载好了数据分析相关的模块,其实无需我们再下载'''
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] # 比例
edu_lv = ['中专','大专','本科','硕士','其他'] # 对应的学历
exp = [0,0.1,0,0,0.5] # 炸开的距离
# 防止图像出错 如果python版本比较低图像可能是扁平的
# plt.axes(aspect='equal')   # 加上这个代码就可以了
'''全部准备好就可以开绘制图形了'''
plt.pie(x = edu,  # 绘图数据
        labels=edu_lv,  # 添加教育水平标签
        autopct='%.1f%%',  # 设置百分比的格式,这里保留一位小数
        explode = exp
       )
%matplotlib()  # 这个东西能让窗口独立展示 跑一遍之后删了这行再跑一遍
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')
'''这部分可能不太好理解前面循环取值
GDP['GDP']这是个带索引的Seriies
那x就是索引 y就是GDP合起来就变成了图上的坐标
然后round是python自带的四舍五入方法
ha是文字形式 居中'''
# 显示图形    
plt.show()

posted @ 2021-10-18 22:31  草卆鱼  阅读(106)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3