Excel 是数据分析中最常用的工具,本篇文章通过 python 与 excel 的功能对比介绍如何使用 python 通过函数式编程完成 excel 中的数据处理及分析工作。在 Python 中 pandas 库用于数据处理,我们从 1787 页的 pandas 官网文档中总结出最常用的 36 个函数,通过这些函数介绍如何通过 python 完成数据生成和导入,数据清洗,预处理,以及最常见的数据分类,数据筛选,分类汇总,透视等最常见的操作。
这个系列文章内容共分为 9 个部分。已由人民邮电出版社出版,感兴趣的朋友可以在 异步社区 获取完整版。
第一篇文章链接在这里: 像 Excel 一样使用 python 进行数据分析 -(1)
本篇文章这是系列的第二篇,介绍第 4-6 部分的内容,数据表生成,数据表查看,和数据清洗。
4,数据预处理
第四部分是数据的预处理,对清洗完的数据进行整理以便后期的统计和分析工作。主要包括数据表的合并,排序,数值分列,数据分
组及标记等工作。
首先是对不同的数据表进行合并,我们这里创建一个新的数据表 df1,并将 df 和 df1 两个数据表进行合并。在 Excel 中没有直接完成数据表合并的功能,可以通过 VLOOKUP 函数分步实现。在 python 中可以通过 merge 函数一次性实现。下面建立 df1 数据表,用于和 df 数据表进行合并。
- #创建df1数据表df1 = pd.DataFrame({
- "id": [1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008],
- "gender": ['male', 'female', 'male', 'female', 'male', 'female', 'male', 'female'],
- "pay": ['Y', 'N', 'Y', 'Y', 'N', 'Y', 'N', 'Y', ],
- "m-point": [10, 12, 20, 40, 40, 40, 30, 20]
- })
使用 merge 函数对两个数据表进行合并,合并的方式为 inner,将两个数据表中共有的数据匹配到一起生成新的数据表。并命名为 df_inner。
- #数据表匹配合并,inner模式
- df_inner=pd.merge(df,df1,how='inner')
除了 inner 方式以外,合并的方式还有 left,right 和 outer 方式。这几种方式的差别在我其他的文章中有详细的说明和对比。
- #其他数据表匹配模式
- df_left=pd.merge(df,df1,how='left')
- df_right=pd.merge(df,df1,how='right')
- df_outer=pd.merge(df,df1,how='outer')
完成数据表的合并后,我们对 df_inner 数据表设置索引列,索引列的功能很多,可以进行数据提取,汇总,也可以进行数据筛选等。
设置索引的函数为 set_index。
- #设置索引列
- df_inner.set_index('id')
排序 (按索引,按数值)
Excel 中可以通过数据目录下的排序按钮直接对数据表进行排序,比较简单。Python 中需要使用 ort_values 函数和 sort_index 函数完成排序。
在 python 中,既可以按索引对数据表进行排序,也可以看制定列的数值进行排序。首先我们按 age 列中用户的年龄对数据表进行排序。
使用的函数为 sort_values。
- #按特定列的值排序
- df_inner.sort_values(by=['age'])
Sort_index 函数用来将数据表按索引列的值进行排序。
- #按索引列排序
- df_inner.sort_index()
数据分组
Excel 中可以通过 VLOOKUP 函数进行近似匹配来完成对数值的分组,或者使用 "数据透视表" 来完成分组。相应的 python 中使用 where 函数完成数据分组。
Where 函数用来对数据进行判断和分组,下面的代码中我们对 price 列的值进行判断,将符合条件的分为一组,不符合条件的分为另一组,并使用 group 字段进行标记。
- #如果price列的值>3000,group列显示high,否则显示low
- df_inner['group'] = np.where(df_inner['price'] > 3000,'high','low')
除了 where 函数以外,还可以对多个字段的值进行判断后对数据进行分组,下面的代码中对 city 列等于 beijing 并且 price 列大于等于 4000 的数据标记为 1。
- #对复合多个条件的数据进行分组标记
- df_inner.loc[(df_inner['city'] == 'beijing') & (df_inner['price'] >= 4000), 'sign']=1
数据分列
与数据分组相反的是对数值进行分列,Excel 中的数据目录下提供 "分列" 功能。在 python 中使用 split 函数实现分列。
在数据表中 category 列中的数据包含有两个信息,前面的数字为类别 id,后面的字母为 size 值。中间以连字符进行连接。我们使用 split 函数对这个字段进行拆分,并将拆分后的数据表匹配回原数据表中。
- #对category字段的值依次进行分列,并创建数据表,索引值为df_inner的索引列,列名称为category和size
- pd.DataFrame((x.split('-') for x in df_inner['category']),index=df_inner.index,columns=['category','size'])
- #将完成分列后的数据表与原df_inner数据表进行匹配
- df_inner=pd.merge(df_inner,split,right_index=True, left_index=True)
5,数据提取
第五部分是数据提取,也是数据分析中最常见的一个工作。这部分主要使用三个函数,loc,iloc 和 ix,loc 函数按标签值进行提取,iloc 按位置进行提取,ix 可以同时按标签和位置进行提取。下面介绍每一种函数的使用方法。
Loc 函数按数据表的索引标签进行提取,下面的代码中提取了索引列为 3 的单条数据。
- #按索引提取单行的数值
- df_inner.loc[3]
- id 1004
- date 2013-01-05 00:00:00
- city shenzhen
- category 110-C
- age 32
- price 5433
- gender female
- m-point 40
- pay Y
- group high
- sign NaN
- category_1 110
- size C
- Name: 3, dtype: object
使用冒号可以限定提取数据的范围,冒号前面为开始的标签值,后面为结束的标签值。下面提取了 0 到 5 的数据行。
- #按索引提取区域行数值
- df_inner.loc[0:5]
Reset_index 函数用于恢复索引,这里我们重新将 date 字段的日期设置为数据表的索引,并按日期进行数据提取。
- #重设索引
- df_inner.reset_index()
- #设置日期为索引
- df_inner=df_inner.set_index('date')
使用冒号限定提取数据的范围,冒号前面为空表示从 0 开始。提取所有 2013 年 1 月 4 日以前的数据。
- #提取4日之前的所有数据
- df_inner[:'2013-01-04']
使用 iloc 函数按位置对数据表中的数据进行提取,这里冒号前后的数字不再是索引的标签名称,而是数据所在的位置,从 0 开始。
- #使用iloc按位置区域提取数据
- df_inner.iloc[:3,:2]
iloc 函数除了可以按区域提取数据,还可以按位置逐条提取,前面方括号中的 0,2,5 表示数据所在行的位置,后面方括号中的数表示所在列的位置。
- #使用iloc按位置单独提取数据
- df_inner.iloc[[0,2,5],[4,5]]
ix 是 loc 和 iloc 的混合,既能按索引标签提取,也能按位置进行数据提取。下面代码中行的位置按索引日期设置,列按位置设置。
- #使用ix按索引标签和位置混合提取数据
- df_inner.ix[:'2013-01-03',:4]
按条件提取(区域和条件值)
除了按标签和位置提起数据以外,还可以按具体的条件进行数据。下面使用 loc 和 isin 两个函数配合使用,按指定条件对数据进行提取 。
使用 isin 函数对 city 中的值是否为 beijing 进行判断。
- #判断city列的值是否为beijing
- df_inner['city'].isin(['beijing'])
- date
- 2013-01-02 True
- 2013-01-05 False
- 2013-01-07 True
- 2013-01-06 False
- 2013-01-03 False
- 2013-01-04 False
- Name: city, dtype: bool
将 isin 函数嵌套到 loc 的数据提取函数中,将判断结果为 Ture 数据提取出来。这里我们把判断条件改为 city 值是否为 beijing 和 shanghai。如果是就把这条数据提取出来。
- #先判断city列里是否包含beijing和shanghai,然后将复合条件的数据提取出来。
- df_inner.loc[df_inner['city'].isin(['beijing','shanghai'])]
数值提取还可以完成类似数据分列的工作,从合并的数值中提取出制定的数值。
- category=df_inner['category']
- 0 100-A
- 3 110-C
- 5 130-F
- 4 210-A
- 1 100-B
- 2 110-A
- Name: category, dtype: object
- #提取前三个字符,并生成数据表
- pd.DataFrame(category.str[:3])
6,数据筛选
第六部分为数据筛选,使用与,或,非三个条件配合大于,小于和等于对数据进行筛选,并进行计数和求和。与 excel 中的筛选功能和 countifs 和 sumifs 功能相似。
Excel 数据目录下提供了 "筛选" 功能,用于对数据表按不同的条件进行筛选。Python 中使用 loc 函数配合筛选条件来完成筛选功能。配合 sum 和 count 函数还能实现 excel 中 sumif 和 countif 函数的功能。
使用 "与" 条件进行筛选,条件是年龄大于 25 岁,并且城市为 beijing。筛选后只有一条数据符合要求。
- #使用"与"条件进行筛选
- df_inner.loc[(df_inner['age'] > 25) & (df_inner['city'] == 'beijing'), ['id','city','age','category','gender']]
使用 "或" 条件进行筛选,年龄大于 25 岁或城市为 beijing。筛选后有 6 条数据符合要求。
- #使用"或"条件筛选
- df_inner.loc[(df_inner['age'] > 25) | (df_inner['city'] == 'beijing'), ['id','city','age','category','gender']].sort
- (['age'])
在前面的代码后增加 price 字段以及 sum 函数,按筛选后的结果将 price 字段值进行求和,相当于 excel 中 sumifs 的功能。
- #对筛选后的数据按price字段进行求和
- df_inner.loc[(df_inner['age'] > 25) | (df_inner['city'] == 'beijing'),
- ['id','city','age','category','gender','price']].sort(['age']).price.sum()
- 19796
使用 "非" 条件进行筛选,城市不等于 beijing。符合条件的数据有 4 条。将筛选结果按 id 列进行排序。
- #使用"非"条件进行筛选
- df_inner.loc[(df_inner['city'] != 'beijing'), ['id','city','age','category','gender']].sort(['id'])
在前面的代码后面增加 city 列,并使用 count 函数进行计数。相当于 excel 中的 countifs 函数的功能。
- #对筛选后的数据按city列进行计数
- df_inner.loc[(df_inner['city'] != 'beijing'), ['id','city','age','category','gender']].sort(['id']).city.count()
- 4
还有一种筛选的方式是用 query 函数。下面是具体的代码和筛选结果。
- #使用query函数进行筛选
- df_inner.query('city == ["beijing", "shanghai"]')
在前面的代码后增加 price 字段和 sum 函数。对筛选后的 price 字段进行求和,相当于 excel 中的 sumifs 函数的功能。
- #对筛选后的结果按price进行求和
- df_inner.query('city == ["beijing", "shanghai"]').price.sum()
- 12230
下一篇文章,也就是本系列的最后一篇我们将介绍 7-9 最后三部分的内容,分别为数据汇总,数据统计和数据输出。请朋友们继续关注 。
来源: http://www.tuicool.com/articles/JvyAFjZ