目录
2.6.2 pandas中的None和np.nan都视为np.nan
0.导引
数据分析三剑客:numpy, pandas, matplotlib
numpy array 提供了运算基础
pandas 提供了业务逻辑的处理方法
matplotlib 做绘图展示
Series,DataFrame
1.Series
一维数组:有序的数据类型相同的集合
Series:一维数组的强化版,增加了像字典一样的key-value一样的访问机制,同时也保留了 数组的访问机制字典:无序的结合
Series是一种类似于一维数组的对象,由下面两个部分组成:
- values :一组数据( ndarray类型)
- index:相关的数据索引标签
1.1 Series的创建
两种创建方式︰
(1)由列表或nunpy数组创建
默认索引为0到N-1的整数型索引
还可以通过设置index参数指定索引
特别地,由numpy创建的是引用,而不是副本(列表创建的是副本) 。对Series元素的改变也会改变原来的ndarray对象中的元素。(列表没有这种情况)
(2)由字典创建
1.2 Series的索引
可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的仍然是一个Series类型)。分为显示索引和隐式索引:
(1)显式索引:
- 使用index中的元素作为索引值
- 使用.loc[](推荐) 配合显式索引
- 使用.iloc[](推荐) 配合隐式索引
- 使用带索引的bool型的Series列表访问
注意,此时是闭区间
(1)隐式索引:
像普通列表一样访问
1.3 Series的切片
1.数组
2.字典
3. s.loc[ ]
4. s.iloc[ ]
注意:默认都是左闭右开区间,所有使用显示索引(即自己设定的index)切片的都是闭区间
1.4 Series常用属性和方法
可以把Series看成一个定长的有序字典。
- 可以通过shape , size , index,values等得到series的属性。
- 可以使用head(),tail()分别查看前n个和后n个值。
- 当索引没有对应的值时,可能出现缺失数据显示NaN ( not a number )的情况。
- 可以使用pd.isnull() , pd.notnull(),或自带isnull(),notnull()函数检测缺失数据。
- Series对象本身及其实例都有一个name属性
- s.sort_values() ==> 根据值排序 s.sort_index() ==> 根据索引排序
- 统计所有值出现的次数:s.value_counts()
1.5 Series的运算
(1)适用于numpy的数组运算也适用于Series
Series和numpy运算,隐式索引对齐;当然也有广播机制
(2) Series之间的运算
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
注意:要想保留所有的index,则需要使用:
- add() 加
- sub() 减
- mul() 乘
- div() 除
1.6 Series练习
1.随机生成两组学生成绩,一组python,一组java,学生包括lucy、mery、tom、jack
2.计算每个学生的平均成绩
3.找出python未及格的学生姓名4.找出java未及格的学生姓名
5.如果需要给mery的python成绩加10分,如何实现6.计算各学科的班级平均成绩
2.DataFrame
DataFrame是一个【表格型】的数据结构(二维),可以看做是【由Series组成的字典】(共用同一个索引)。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。
- 行索引:index
- 列索引:columns
- 值:values ( numpy的二维数组)
2.1 DataFrame的创建
最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。此外,DataFrame会自动加上每一行的索引(和Series一样)。
同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。
DataFrame属性:values、columns、index、shape
三种创建方法:
- 构造函数构造 ==>不建议这种,因为每一列数据是一样的
- 字典构造 ==>建议这种,因为每一列数据可以不一样
- 从文件中读取DataFrame文件 ==> pd.read_csv() pd.read_table() pd.read_excel()
- 使用Series构造DataFrame
2.2 DataFrame的索引
(1)对列进行索引
- 通过类似字典的方式
- 通过属性的方式
可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
(2)对行进行索引
- 使用.ix[ ]来进行行索引
- 使用.loc[ ]加index来进行行索引
- 使用.iloc[ ]加整数来进行行索引
同样返回一个Series , index为原来的columns。
(3)对元素索引的方法 ==> 元素访问的逻辑和numpy的访问逻辑一致(先行后列)
- 使用列索引
- 使用行索引(iloc[3,1]相当于两个参数;iloc[[3,3]]里面的[3,3]看做一个参数)
- 使用values属性(二维numpy数组)
2.3 DataFrame的切片
【注意】直接用中括号时:
- 索引表示的是列索引
- 切片表示的是行切片
标签处理的切片都是闭区间。
列切片:逻辑和二维数组一样,想切列,必须先把行全部保留下来
2.4 DataFrame的运算
运算的三种情况:
- DataFrame和一个数 ==> 广播机制
- DataFrame和数组(numpy、Series) ==> 索引对齐,axis控制方向
- DataFrame和 DataFrame ==> 索引对齐,不分方向
( 1 ) DataFrame之间的运算
同Series一样:
- 在运算中自动对齐相同索引的数据
- 如果索引不对应,则补NaN
默认运算都是列方向
df.mean() df.sum()
2.5 DataFrame练习
练习:
1.假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。2.假设张三期中考试数学被发现作弊,要记为0分,如何实现?
3.李四因为举报张三作弊立功,期中考i试所有科目加100分,如何实现?
4.后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
2.6 pandas中的None和np.nan
2.6.1 基本概念
有两种丢失数据:
- None
- np.nan(NaN)
在python中尽量用NaN,而不是要用None,因为对象比int类型运算慢的多。
None:None是Python自带的,其类型为python object。因此,None不能参与到任何计算中。
object类型的运算要比int类型的运算慢得多
计算不同数据类型求和时间
%timeit np.arange(1e5,dtype=xxx).sum()
np.nan:
np.nan和任何数运算,得到结果还是nan。
np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。
但可以使用np.nan*()函数来计算nan,此时视nan为0。
2.6.2 pandas中的None和np.nan都视为np.nan
pandas会把None优化为np.nan。
2.6.3 pandas中的None与np.nan操作
- isnull()
- notnull()
- dropna( ):过滤丢失数据
可以选择过滤的是行还是列(默认为行)
也可以选择过滤的方式how = 'all'- fillna():填充丢失数据
==> 通常的办法就是是用每一列的某一个聚合指标来对每一列进行填充
可以选择前向填充还是后向填充;向前:从下/右往上/左,向后:从上/左往下右
‘backfill' 'bfill' 'pad' 'ffill'
对于DataFrame来说,还要选择填充的轴axis。记住,对于DataFrame来说:axis=0:index/行
axis=1:columns/列
3.pandas多层级索引
3.1 多层级索引的创建
1)隐式构造
最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组
- Series也可以创建多层索引
2)显示构造pd.Multilndex
- 使用数组
- 使用tuple
- 使用from_product ==> 最简单,推荐使用
3.2 多层级索引的访问与切片
多层级索引访问的核心:
1.多层级的索引的表达方式变成元组
2.隐式索引的访问方式不受影响建议隐式索引,这样不用写乱七八糟的元组。 ==> 隐式索引永远是单层的
1) Series的操作
【重要】对于Series来说,直接中括号[ ]与使用.loc[ ]完全一样,推荐使用.loc[ ]和切片。
- 索引
- 切片
2) DataFrame的操作
- 可以直接使用列名称来进行列索引
行多级索引的索引和切片操作
列多级索引的索引和切片操作- 使用行索引需要用ix(),loc[ ]等函数
【极其重要】推荐使用loc[ ]函数
注意:在对行索引的时候,若一级行索引还有多个,对二级行索引会遇到问题!也就是说,无法直接对二级索引进行索引,必须二级索引变成一级索引后才能对其进行索引!
多级索引用元组表示,其余与Series访问一样。
3.3 多层级索引的变形操作(stack)
- stack() ==> column变成index
- unstack() ==> index变成column
【小技巧】使用stack()的时候,level等于哪一个,哪一个就消失,出现在行里。
【小技巧】使用unstack()的时候,level等于哪一个,哪一个就消失,出现在列里。
==> 从里往外数,就是-1 -2 -3;从外往里数,就是0 1 2
4.pandas汇总操作
pandas的拼接分为两种:
- 级联:pd.concat,pd.append
- 合并:pd.merge,pd.join
4.1 级联
4.1.1 使用pd.concat()级联
- 级联方向上的形状不同,同样可以连接
- 以索引对齐的方式连接,所以跟顺序没关系
pandas使用pd.concat函数,与np.concatenate函数类似,只是多了一些参数:
objs ==> 要参与级联的pandas对象的列表、元组
axis=0
join='outer'join_axes=None
ignore_index=False ==> 原始索引无意义,可以忽略索引级联
keys ==> 可以弄多级索引
- 原始表的索引没有实际意义,可以忽略处理,用ignore_index避免重复;
- 如果级联后,原始索引不能忽略,但又希望避免重复,可以用keys做成多层级表格
4.1.2 不匹配级联
不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致
有3种连接方式:
- 外连接:补NaN(默认模式) ==> outer 保存连接的表的所有字段,缺失值补空值
- 内连接:只连接匹配的项 ==> inner 只保留公共字段 【不建议】
- 连接指定轴 join_axes
4.1.3 使用append()函数添加
由于在后面级联的使用非常普遍,因此有一个函数append专门用于在后面添加。
注意:append函数只是沿着axis=0的方向进行级联
4.2 合并
合并只跟列有关,两张表要去找默认内容相同的列来进行合并,也可以columns不相同。
合并的两张表一定存在至少一列,在内容上有对应关系:
- 一对一合并
- 多对一合并
- 多对多合并
- key的规范化 ==> 1.使用on=显式指定哪一列为key,当有多个key相同时使用;
==> 2.使用left_on和right_on指定左右两边的列作为key,当左右两边的 key都不想等时使用。合并可以同时参考多列进行,这取决于你的业务需求。
merge与concat的区别在于,merge需要依据某一共同【列】来进行合并
使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。注意:每一列元素的顺序不要求一致
4.2.1 一对一合并
4.2.2 多对一合并
4.2.3 多对多合并
4.2.4 key的规范化
4.2.5 没有相同的columns也可以合并
4.2.6 内合并与外合并
- 内合并:只保留两者都有的key (默认模式)
- 外合并how='guter':补NaN ==> 【推荐使用】
- 左合并、右合并: how='left' , how='right' ==> 根据左表和右表来保留内容
pd.merge()
1.都是以列为合并项;
2.参与合并的列必须满足一对一、一对多、多对多关系中的至少一种;3.参与合并的列的选择应该是选择离散型数据而不是连续型数据。
- how='inner'合并的方式内合并外合并左合并右合并
- on指定参与合并的列用于有多列标签相同的情况
- left_on\right_on分别制定左右表参与合并的列用于两张表参与合并的列标签不同的情况
- suffiexes一般与on参数一起使用,给相同列标签但是没有参与合并的列添加后缀
- left_index\right_index指定索引作为合并的参考值
merge的内合并与concat的内合并的区别:
- inner内合并,只保留相同的【内容】
- concat 的内连接:只保留相同的【标签】
4.2.7 列冲突的解决
当列冲突时,即有多个列名称相同时需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名;
可以使用suffixes=自己指定后缀。
4.2.8 简易回顾+练习
【简易回顾】
【练习一】
【练习二】
假设有两个同学都叫李四,ddd5、ddd6都是张三和李四的成绩表,如何合并?
5.pandas的数据处理
先了解数据:
- df.read()
- df.info()
- df.description()
原始数据最基本的操作包括如下三步:
- 空值的处理
- 重复值的处理
- 异常值的处理
5.1 删除重复元素
使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True
- 使用drop_duplicates()函数删除重复的行
- 使用duplicated()函数查看重复的行
如果使用pd.concat([df1,df2],axis = 1)生成新的DataFrame,新的df中columns相同,使用duplicate()和drop_duplicates()都会出问题。
5.2 映射
映射的含义︰创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定包含三种操作︰
- replace()函数︰替换元素(DataFramelSeries的函数)
- 最重要:map()函数︰新建一列(Series的函数)
- rename()函数:替换索引(DataFrame的函数)
fillna和replace的区别:fillna负责空值的填充,而replace是任意值的填充。即replace是fillna的高级版本。
5.2.1 replace()函数:替换元素
使用replace()函数,对values进行替换操作。
Series替换操作:
- 单值替换
- 列表替换
- 字典替换(推荐)
Series参数说明∶
- method:对指定的值使用相邻的值填充
- limit:设定填充次数
1)替换字符串
2)替换数字
3)使用列表替换多个值
4)使用字典替换
5)使用字典处理某一列的替换
6)正则表达式替换
7)填充
8)小练习
假设课表里有满分的情况,老师认为是作弊,把所有满分的情况r(包括150,300分)都记0分,如何实现?
5.2.2 map()函数:新建一列
map是Series的函数,所以通常被用来对某一列进行整体的映射处理。
- map()可以使用字典映射新─列数据
- map()中可以使用lambd表达式
- map()中可以使用方法,可以是自定义的方法
注意:
- map()中不能使用sum之类的函数,for循环
- map(字典)字典的键要足以匹配所有的数据,否则出现NaN
1)使用字典映射
2)使用方法映射
3)lambda处理
5.2.3 小练习
新增两列,分别为张三、李四的成绩状态,如果分数低于90,则为"failed",如果分数高于120,则为"excellent",其他则为"pass"。
【提示】使用函数作为map的参数
5.2.4 rename()函数:替换索引
使用rename()函数替换行索引:
- mapper替换所有索引
- index替换行索引
- columns替换列索引
- level指定多维索引的维度
5.3 使用聚合操作对数据异常值检测和过滤
使用describe()函数查看每一列的描述性统计量。 ==> 只对可以运算的列有效
使用std()函数可以求得DataFrame对象每一列的标准差。==> 异常值的通用界定方法
|data|>3*|std()|
离群点的检测:数值型的数据都可以使用离群点的方式来检测异常
5.3.1 查看表格数据信息的常用方法
df.dtypes df.head() df.tail() df.info() df.describe()
5.3.2 异常值处理
异常值通用的界定办法:
- 如果数据是呈标准正态分布的,/data >3*/data.std()/
- 离群点的检测:数值型的数据都可以使用离群点的方式来检测异常
5.4 排序
使用.take()函数排序:
take()函数接受一个索引列表,用数字表示eg : df.take([1,3,4,2,5])
可以借助np.random.permutation()函数随机排序
随机抽样:
当DataFrame规模足够大时,直接使用np.random.randint()函数,就配合take()函数实现随机抽样。
1)排序
2)随机抽样
5.5 数据分类/组处理【重点】
数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。
数据分类处理:
- 分组:先把数据分为几组
- 用函数处理:为不同组的数据应用不同的函数以转换数据
- 合并:把不同组得到的结果合并起来
数据分类处理的核心:
- groupby()函数
- groups属性查看分组情况
交叉表:
交叉表(cross-tabulation,简称crosstab)是一种用于计算分组频率的特殊透视表。
透视表:
透视表(pivot table)是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行聚合,并根据行和列上得分组建将数据分配到各个矩形区域中。在Python和pandas中,可以通过本章所介绍的groupby功能以及(能够利用层次化索引的)DataFrame有一个pivot_table方法,此外还有一个顶级的pandas.pivot_table函数。除了能为groupby提供便利之外,pivot_table还可以添加分项小计(也叫margins )。
5.5.1 单字段分组
5.5.2 多字段分组
5.5.3 透视表
透视表:
透视表(pivot table)是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行聚合,并根据行和列上得分组建将数据分配到各个矩形区域中。在Python和pandas中,可以通过本章所介绍的groupby功能以及(能够利用层次化索引的)DataFrame有一个pivot_table方法,此外还有一个顶级的pandas.pivot_table函数。除了能为groupby提供便利之外,pivot_table还可以添加分项小计(也叫margins )。
5.5.4 交叉表
交叉表:
一种特殊的透视表, 用于统计个数。直接对一个对象操作。
交叉表(cross-tabulation,简称crosstab)是一种用于计算分组频率的特殊透视表。
5.6 高级聚合
使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算。
- df.groupby("item')['price'].sum() <==> df.groupby('item')['price'].apply(np.sum)
- transform和apply都会进行运算,在transform或者apply中传入函数即可
- transform和apply也可以传入一个lambda表达式
注意:
- transform会自动匹配列索引返回值,不去重
- apply 会根据分组情况返回值,去重
5.6.1 apply()函数
5.6.2 transform()函数
注意:
- transform会自动匹配列索引返回值,不去重
- apply 会根据分组情况返回值,去重
5.6.3 小练习
假设菜市场张大妈在卖菜,有以下属性︰
菜品(item):萝卜,白菜,辣椒,冬瓜颜色(color):白,青,红
重量(weight)
价格(price)
1.以属性为列索引,创建一个DataFrame对象df2.对df进行聚合操作,求出颜色为白色的价格总和
df. groupby ("color")["price"].sum()
3.对df进行聚合操作,求出萝卜的所有重量(包括白萝卜,胡萝卜,青萝卜)以及平均价格r = df.groupby("item").agg({"weight" :"sum" ,"price" :"mean"})
4.使用merge合并总重量及平均价格
pd.merge(df, r,left_on="item",right_index=True)
附载numpy学习链接:
numpy学习https://mp.csdn.net/mp_blog/creation/editor/125643490