====== 数据处理 ======
===== 学习目标 =====
* 掌握pandas中数据处理的具体方法
* 理解数据清洗的概念,并掌握使用pandas进行数据清洗的方法
* 掌握数据抽取的方法
----
===== 学习内容 =====
对数据的处理一般有以下几个方面:
* 数据清洗
* 数据抽取
* 排名索引
* 数据合并
* 数据计算
* 数据分组
==== 数据清洗 ====
数据清洗的''目的''是:提高数据质量。数据清洗的''主要任务''是:处理缺失数据及清除无意义的信息。
=== 重复值的处理 ===
数据录入过程、数据整合过程都可能会产生重复数据,直接删除是重复数据处理的主要方法。
pandas提供查看、处理重复数据的方法:''duplicated()'' 和 ''drop_duplicates()''
以下代码演示如何查询重复值
>>> sample = pd.DataFrame({'id':[1,1,1,3,4,5],'name':['Bob','Bob','Mark','Miki','Sully','Rose'],'score':[99,99,87,77,77,np.nan],'group':[1,1,1,2,1,2],})
>>> sample.duplicated() # 以布尔值的形式反馈重复的行
>>> sample[sample.duplicated()] # 出示重复数据
以下代码演示如何去除重复值
>>> sample = pd.DataFrame({'id':[1,1,1,3,4,5],'name':['Bob','Bob','Mark','Miki','Sully','Rose'],'score':[99,99,87,77,77,np.nan],'group':[1,1,1,2,1,2],})
>>> sample.drop_duplicates() # 括号中可设置列名,从而对指定列进行去重。查重亦可。
=== 缺失值的处理 ===
数据处理面向的对象更多是我们所说的大数据,大数据中的价值密度低,很多时候会出现值的缺失等等这样一些问题。
对于缺失数据一般的处理方式有:
* 删除缺失值
* 增补缺失值
* 不处理
**简单粗暴型——删除缺失值**
使用dropna()函数去除数据结构中值为空的数据行。一般步骤为:
* 使用isnull()函数来检测是否存在缺失值的情况
** 可以使用df.isnull().any()查看哪些列有缺失值
** 可以使用df.apply(lambda col:sum(col.isnull())/col.size)来查看缺失比例
** 可以使用df[df.isnull().values==True]查看具体缺失值的列
** 可以使用np.sum(df.isnull(),axis=0)来统计每一列缺失值的数量
* 使用dropna()函数来删除缺失值的行
''用指定值来填补缺失值''
* 指定一个字符或数值来填充空白处,`df.fillna('#')`
* 使用前一个数据值来替代缺失值,`df.fillna(method='pad')`
* 使用后一个数据值来替代缺失值,`df.fillna(method='bfill')`
* 使用平均数或其他描述性统计量来替代缺失值,
`df.fillna(df.mean())--平均值
df.fillna(df.median())--分位数`
pandas使用strip()函数来清除字符型数据首尾指定的字符,默认为空格,中间的不清除。如:
newDF=df['loan_staus'].strip()
=== 异常值的处理 ===
在一组数据当中,有时候会出现一些异常数据(不符合实际,特别大或特别小),这些数据会影响到后续的处理。因此,对于这些个别值(离群点)需要去进行处理。
使用方法对数据中的异常数据进行发现。
例如:describe()就可以对每一列数据进行统计,包括计数,均值,std,各个分位数等。通过观看这些数值之间的关系从而进行判断与调整。
==== 数据抽取 ====
数据抽取就是从数据集中将需要用到的数据信息提取出来的操作。
=== 字段抽取 ===
pandas用slice()函数抽出某列上指定位置的数据,做成新的列。函数的使用方法如下:
>>> df.str.slice(start,stop)
>>> df.str.slice(0,3) #设置起始终止范围
>>> df.str.slice(6) #设置起始点
=== 字段拆分 ===
pandas用split()函数按指定的字符拆分已有的字符串。函数的使用方法如下:
>>> split(sep,n,expand=False)
#sep->用于分割的字符串
#n -> 分割后新增的列数,要注意,n+1应该与实际切割后的字符串列数相等
#expand -> True时返回DateFrame,False时返回Series
=== 记录抽取 ===
pandas可以根据一定的条件对数据进行抽取。常见格式如:`DataFrame[condition]
`
对于condition中的常见类型有:
* 比较运算符:<、>、<=、>=、!=
* 范围运算:between(left,right)
* 空置运算:isnull(column)
* 字符匹配:str.contains(pattern,na=False)
* 逻辑运算:&、|、not
* 多个数值匹配:isin()
使用范围如下:
>>> df[df.grade=='A'] # df[df['grade']=='A']
>>> df[df.loan_amnt > 25000] #df[df['loan_amnt'] > 25000]
>>> df[df.loan_amnt.between(25000,35000)]
>>> df[df.annual_inc.isnull]
>>> df[df.emp_length.str.contains('10+',na=False)]
>>> df[df.sth.isin([a,b,c,d])]
>>> df[(df.loan_amnt > 25000) & (df.loan_amnt<35000)]
=== 随机抽样 ===
使用randint生成随机数,再将其作为索引值代入DataFrame,从而实现随机抽样。
>>> rand = np.random.randint(0,10,3)
>>> df.loc[rand]
=== 切片抽取 ===
切片抽取即是根据一定条件,以切片的方式对数据集进行抽取。常见的切片方式有三种。第一种、第二种方法在DataFrame数据查询时均已重点讲解过,不再赘述。
1.loc方法
DataFrame.loc[行索引名称或条件,列索引名称]
>>> df.loc[3:8]
>>> df.loc[3:8,'loan_status']
>>> df.loc[3:8,'loan_status':'emp_length']
2.iloc方法
DataFrame.iloc[行索引位置条件,列索引位置条件]
>>> df.iloc[3:8,2:5]
>>> df.iloc[[2,3,5],[1,2,6]]
>>> df.loc[3:8,'loan_status':'emp_length']
3.ix方法
DataFrame.ix[行索引名称、位置、条件,列索引名称、位置]
ix方法是loc和iloc两种切片方法的整合。即可以接收索引名称,也可以接收索引位置。但在使用时需要注意以下几个方面:
(1)使用ix参数时,尽量保持行索引名称和行索引位置重叠,使用时就无须考虑取值敬意的问题。
(2)使用列索引名称,而非列索引位置,主要用来保证代码的可读性。
(3)使用列索引位置时需要注解,同样用来保证代码的可读性。
ix的缺点是在面对数据量巨大的任务时,其效率会低于loc和iloc方法。
=== 字典数据 ===
DataFrame可以从字典进行创建,所以将字典数据抽取为DataFrame时也就非常方便。主要有以下三种方法。
* 将字典中的key和value各作为一列;
* 将字典中的每一个元素作为一列(同长);
* 将字典中的每一个元素作为一列(不同长);
以上三种方法创建范例分别如下:
第一种:
>>> d1 = {'a':'[1,2,3]','b':'[4,5,6]'}
>>> a1 = pd.DataFrame.from_dict(d1,orient='index')
>>> a1.index.name='key'
>>> b1 = a1.reset_index()
>>> b1.column=['key','value']
第二种:即为一般DF的创建方法,略过
第三种:
>>> d1 = {'a':pd.Series([1,2,3]),'b':pd.Series([4,5,6,7])}
>>> a1 = pd.DataFrame(d1)
==== 排名索引 ====
=== 排序 ===
排序是数据处理时的一种常见操作,在pandas当中对数值进行排序主要使用sort_index()函数。
* 对于Series,sort_index()函数中包含ascending参数。当值为True时进行升序排序,当值为False时,进行降序排序。
* 对于DataFrame,sort_index()函数中还包含axis和by参数。axis表示排序轴,1为横向,0为纵向。by表示可选择字段进行排序。
=== 排名 ===
排名函数rank()用来对一组数据进行排名,如存在一组数据4、3、2、3,如果要从小到大对该组数据进行排名,应该排成如下图所示:
| 数值 | 4 | 3 | 2 | 3 |
| 排名 | 4 | 2 | 1 | 2 |
以上是常规排名方式,在pandas中对于相同两值的排名,默认采取的不是从上一值顺延下来,而取相同值顺次排名下来的平均值。
| 数值 | 4 | 3 | 2 | 3 |
| 排名 | 4.0 | 2.5 | 1.0 | 2.5 |
rank()函数参数之二method,其值有4个可选项
* average-- 默认,取平均值
* min -- 如有重复值,均取第1个值出现的排名
* max -- 如有重复值,均取最后一个值出现的排名
* first -- 如有重复值,按照出现顺序依次排名
rank()函数对于DataFrame而言,比Series多了一个参数,即axis。
即:排名的方向。
=== 重新索引 ===
使用reindex()函数对Series对象进行索引重建。
reindex()函数有两个参数,即fill_value和method。
* fill_value对重建后的内容为空的值进行指定值的填充。
* method指定填充方式,ffill/pad 向前或进位填充,bfill/backfill 向后或进位填充。
使用reindex()函数也可对DataFrame对象进行索引重建。
此时的参数中多了一个columns参数,用以设置重建的列名。
=== 数据合并 ===
所谓堆叠合并数据,就是将两个表按照一定的要求拼在一起。根据拼接的方向,可以分为横向堆叠和纵向堆叠。
=== concat() ===
concat()函数的基本语法
concat(objs,axis=1,join='outer',join_axes=None,ignore_index=False,keys=None,levels=None,names=None,verify_integrity=False)
* 当axis = 1的时候,concat就是行对齐,然后将不同列名称的两张表合并
* 加上join参数的属性,如果为’inner’得到的是两表的交集,如果是outer,得到的是两表的并集
* join_axes的参数传入,可以指定根据那个轴来对齐数据
* 如果两个表的index都没有实际含义,使用ignore_index参数,置true,合并的两个表就会根据列字段对齐,然后合并。最后再重新整理一个新的index。
=== append() ===
使用append来对数据进行纵向合并。
result = df1.append(df2,ignore_index=False,verify_integrity=False)
append要求合并的两张表的列名要完全一致。
* `ignore_index`:True为重新索引
* `verify_integrity`:检查数据索引是否冲突