====== 数据处理 ====== ===== 学习目标 ===== * 掌握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`:检查数据索引是否冲突