用Python进行数据分析的基础姿势(一)

版权声明

本文首发于微信公众号

沁机迈可思(zw_life-long_doing)

无需授权即可转载

转载时请注明出处

如同我们做其他事情一样,数据分析也是有一定流程的。它一般分为四步:

确定问题->分解问题和数据->评估数据->作出决策

确定问题很好理解,就是确定方向。因为只有当我们先清楚自己处理这一大堆数据的目的是什么,才能指导我们快速向前,否则就像一只没有目的得苍蝇一样,在数据里来回兜圈。

一般来说,我们确定问题的对象是我们的“客户”。他可能是你的上司,也可能是公司的业务部门,甚至可能是你自己。当我们对问题有什么疑问的时候,一定要跟自己的“客户”对接到位,可不要自己想当然的理解。

在确定了问题之后,我们要做的,就是分解问题和数据。到这一步,你可能会问,知道了问题是什么,有了数据,不应该着实开始处理数据吗,为什么还要分解一遍?

和确定问题的逻辑差不多。我们得大量的数据里面,提取出与问题相关的数据,进行处理和分析,以达到效率的最大化。因此,我认为这也是数据分析师在拿到原始数据的时候,应有的一种意识,也可以说成是理解数据

但同时,我们也不要忘了要分解问题。因为在大多数的情况下,一个大的问题,解决起来往往是比较困难的,也是相对复杂的。那么,这个时候我们就可以把大的问题分解成一个个相关的小问题,再逐一突破,毕竟小问题处理起来更简单一些嘛。当这些小问题有了答案之后,那大问题的答案自然而然就有了。

接下来,就是评估数据了。在这里面,有两个方面需要注意。一个是对分解出来的数据,进行预处理,以适合我们操作习惯;另一个则是对这些数据进行深入的挖掘和分析,形成自己的判断。

最后一步,就是作出自己的决策,以报告的形式向“客户”输出我们判断,让它产生价值。在这一步里面,数据可视化是很常用的一个工具。

可以说,在我们每一次的数据分析中,都少不了这四步流程。但是,当我们使用Python进行数据分析的时候,仍有很多和平时不一样的地方。本文就先从数据分析包的选择、数据清洗这两个方面来谈谈“用Python进行数据分析的基础姿势”。

数据分析包的选择

我们选择数据分析包的目的很简单,无非为了更好更快的理解数据。所以,在这之前,我们需要了解用Python进行数据分析的两个常用包:Numpy与Pandas

Numpy包

Numpy是一个高性能科学计算和数据分析的基础包。这个包本身并没有提供多么高级的数据分析功能,但是理解Numpy数组以及面向数组的计算将有助于我们更高效的使用Pandas之类的工具

说到Numpy包,它最重要的一个特点就是其N维数组对象(即ndarray)。可以理解它是一个大数据集容器,我们可以利用这种数组对整块数据执行一些数学运算。

既然是数组,那么就涉及到怎么创建一个数组。在Numpy包里,无论是创建一个一维数组还是多维数组,都是函数。

因为ndarray是一个通用的同构数据多维容器,因为其中的所有元素必须是同一类型。其中的每个数组都可以用函数来表示各维度大小,用来说明数组是哪类数据类型。

这里说说数值型的命名方式:一个类型名,后面跟一个用于表示各元素位长的的数字。比如上图中的,前面的表示Python中的浮点型,后面的“64”表示这个对象需要占用8字节(即64位)的位长。

一般情况下,我们除了用函数查看数组的数据类型外,也可能遇见更改它数据类型的情况。这个时候我们就要用到函数,下图我们更改一下arr1的数据类型。

发现了吗?当我们更改了数组的数据类型之后,它表示的值也会相应的发生改变。比如上图中,我们更改之前的为,原来arr1数组中元素的小数位就被砍掉了。

在Numpy中,数组的索引算得上是一个很丰富的内容,而且在对数组进行计算的时候,也可能会用到这个功能,尤其在多维数组中。

一维数组比较简单,它和列表类型的功能差不多。我们重新定义一个一维数组来说明一下。

但对于一个高维数组而言,各索引位置上的元素不再是标量,而是一个数组,而且花样更多。

在高维数组中的,需要注意的是:“只有冒号,没有数字”表示选取整个行(或列)的数据

讲了索引,那接下来讲讲数组中的运算。在数组的运算中,对某数组进行算术运算,甚至是与大小相等的数组进行任何算术运算,都会逐个对所有元素进行运算。这在一维数组与高维数组中并没有什么差别。因此,这里就只拿一维数组举例。

但是在进行数据分析的时候,我们不一定需要所有的元素统计计算,可能只需要行,或者列的计算结果。这个时候,就需要用到一个参数。在高维数组中,若axis = 1,它代表所有行的数据;若axis = 0,它代表所有列的数据。

也正是由于Numpy在运算时的会遍历所有元素的特性,我们可以将许多种数据处理任务表述为简洁的数组表达式。这种用数组来代替循环的做法,通常被称为矢量化。

一般来说,矢量化数组运算会比等价的纯Python方式快上一两个数量级,尤其是各种数值计算。比如说,一只蜗牛,从0开始随机的向前(步长1)或者后退(步长-1)行走,步长1与-1出现的概率相等。我们可以怎么来实现呢?

纯Python的方法(用循环)

矢量化数组计算的方法

相信细心的你,一定发现了:通过纯Python用循环的方式,得到的结果是列表类型,需要进一步的转换为数组才能进行最大值、最小值或是其他的统计计算。而矢量化的数组计算的运算结果,直接就是数组了,方便很多。而且实现的步骤也比纯Python要短不少。

当然,这也仅仅最简单的利用数组来处理数据,但更高阶的内容在本文不做涉及。

Pandas包

Pandas是基于Numpy构建的,含有使数据分析工作变得更快更简单的高级数据结构和操作工具。它有两个主要的数据结构,一个是“Series”,一种类似于一维数组的对象;另一个是“DataFrame”,是一种表格型的数据结构。

先来说说Series,它是有一组数据以及一组与之相关的数据标签(即索引)组成,仅有一组数据就可以产生最简单的Series数据表。

Series字符串的表现形式为:索引在左边,值在右边。如果我们没有为数据指定索引的话,那它就会自动的创建一个0到N-1的索引。也就是说,我们可以自定义索引。

与Numpy数组中选取数据的方式不同。在Series表中,我们除了按照位置选取以外,还可以通过它的索引来选取对应的单个或一组值。

回忆一下,按照索引来选取对应值的数据类型,还有哪一个,字典是不是也是这样的过程呢?换句话,我们是不是可以通过一个字典,来建立一个Series表呢?事实证明是可以的哈,因为它也是索引值到数据值的一个映射嘛。

和Numpy的数组一样,Series表也可以进行向量化运算。不同的是,Numpy的数组必须是等量步长的数组才能进行向量化运算,而Series在运算中会自动对齐不同索引的数据。

上图中,因为在c表中没有对应索引“b”的值,所以b表与c表相加后,会出现缺失值“NaN”的情况。至于怎么处理缺失值,我放在DataFrame中来介绍。

关于Series表的基本知识,上面就讲的就差不多了。接下来讲一讲DataFrame(数据框)的基础知识。

DataFrame是一个以二维结构保存数据的表格型数据结构,它既有行索引也有列索引,可以被看做是由多个Series组成的字典。但与Numpy高维数组中需要统一数据类型的情况不同,DataFrame中允许有不同数据类型存在,每列的值可以是字符串,也可以是布尔值。

这个特性也说明了我们在处理高级数据的时候,会更多的用到DataFrame这个数据结构。

构建DataFrame的方法有很多,比较常用的是直接传入一个有等长列表或Numpy数组组成的字典,另一种常见的形式是嵌套字典。

在DataFrame中,我们有四种方法来获取自己想要的值。

在这四种方式里面,我建议用函数通过索引来选取你想要的值,因为某个表的索引是很清晰的,通过索引来选取数据一般不会出什么岔子。而且在很多时候,我们选取数据的时候不会选取单个数据,通常是选取多行多列的数据,这个时候怎么办呢?

同时,我们也可以设计一个条件来选取数据。

下图表格总结了可以输入给DataFrame数据框的数据结构。

最后,讲一讲在Series与DataFrame中的数据的基本手段。

重新索引

在重新索引功能中,pandas对象的一个重要方法是。这里要注意是,对于来说,可以修改索引和列中的其中一个,或者两个都修改。

下图总结一下在函数涉及到的一些参数。

排序

根据条件对数据集进行排序也是一种重要的内置运算。如果我们要对任意轴上的的索引(或值)进行排序,可使用(或)的方法。

处理缺失数据

pandas使用浮点值“NaN”表示浮点和非浮点数组中的缺失数据。在面对缺失值的时候,我们通常有两种处理方法:删除和填充

过滤掉缺失数据的方法有很多,但这里面,使用“dropna”函数会比较实用一些。在Series表中,因为只有一列数值,所以会直接删除这一列里的所有缺失值。但对于DataFrame对象来说,就不是这么简单了。因为你可能希望滤掉所有的缺失值,也可能希望仅滤掉含有缺失值的行或列。

在使用函数的时候,通常它有个参数。若表示删除全部为缺失值的某行/列;若表示删除任一含有缺失值的某行/列;使用则指定对象中至少需要包含多少个控制才会被删除等等。

当然,我们处理删除缺失值以外,还可以对它进行填充动作。大多数情况下,我们使用“fillna”函数来解决。

汇总和计算描述统计

在利用Python处理数据的时候,我们难免会遇见求和或者求均值的情况。理论上来说,这里是比较简单的。但是有一个知识点,需要详细说明一下。也就是这个参数在DataFrame中的指向问题。先来看一个例子。

注意看红框圈出来的地方。在我们要删除某一列的时候,使用的是“axis=1”,但是当我们在计算每一行均值的时候,也是使用的“axis=1”,为什么同一个语句,会出现两个不同的使用场景呢?

开始的时候我也是蒙的。但是换个思路,就清晰了:axis=1,指的是沿着行求所有列的平均值,代表了横轴;而axis=0,则是沿着列求所有行的平均值,代表了纵轴。而,语句,就是沿着这一列的方向,删除掉所有行的数据,所有。看了下面的图,我相信你更清晰一些。

最后总结一下我们在处理数据的时候,可能会用到的描述和汇总统计语句。

以上便是Numpy与Pandas包的基本运用,接下来就结合上面的知识讲一讲我们在进行数据清洗的时候需要走哪些流程。

数据清洗

在我们进行数据分析的过程中,可以说有60%的时间是花在了数据清洗上的,比如说处理缺失值,删除异常值等等。我们进行数据预处理的目标,是把数据改变成我们喜欢的样子,方便后面对他进行深入的分析。

一般来说,我们进行数据清洗的步骤可以分为六步,分别是选择子集->列表重命名->缺失数据处理->数据类型转换->数据排序->异常值处理

我们先导入一个“豆瓣热门电影.xlsx”数据表。

然后再通过选择子集的方式,来选取我们想要的行和列,并看看现在数据表的基本信息。

这里我选择的事剔除掉编剧、主演等列,因为这些列的数据对我们了解豆瓣整个热门电影榜单来说,并不那么重要。所以我用了函数来删除掉我不要的列,重新赋值给了文件。

接下来对列表进行重命名操作,比如将上映年份重新命名为上映时间。这里用到的是函数,并引入了一个参数,目的是告诉计算机这个更改是否在原表上进行,而不用新建一个副本。表示着新建一个副本,这个参数默认是。

但是在处理缺失数据的时候,我们需要吹到这个表里面是否有缺失数据。这个时候有两种方式,一个是用或者函数判定表中是否含有缺失值数据,结果返回一个布尔值,然后用条件判断这表里是否有的情况。这个语句会比较清晰,但是我个人觉得在效率上会有一点麻烦,因为要写两次代码。所以,这里我就用函数来计算所有列的非空值的数量。因为我们知道整张表有280行,如果哪一列低于了这个值,就说明这里有缺失值。

接下来就是转换数据类型,因为我们在导入数据表的时候,为了避免数据显示有误,所以统一导入的事字符串类型。但是字符串类型是不能进行计算的,所以我们需要把部分数据转换成我们需要的整形或者浮点型。即把“上映时间”这列改为日期格式,将和这两列分别改成浮点型和整形

这时,要用到和函数了。但是这里要注意两点:

在DataFrame中,如果我们要更改某列的数据列,我们需要把这一列选取出来再替换,最后赋值到对应的地方。

参数表示的是原数据表中的时间格式。因为原数据表中只有年,因此这里是。

同时,我们看到这列的数据类型仍然是字符串类型。但由于它的值是数字和字符串的组合,所以我们不能进行简单的改变,需要先将它们分割开来。因此,我考虑用函数通过分隔符的方式对字符串进行简单切片。

但也正如我们演示的那样,通过分割后的字符串是一个列表类型,如果我们需要对列表进行统计操作的话,就需要将这个列表生成数组才能进行计算。所以,我们需要定义一个循环函数,将分割后的列表数据生成一个数组。然后修改数据表中的值,最后批量赋值修改。

在对数据类型进行了转换之后,我们需要将这个数据表按照我们自己想要看到结果进行排序。这里呢,我们就按照这一栏对这个数据表进行重排。

最后,我们来看看在这些电影里面,是否有没有人评价的情况。如果有的话,就把它踢掉。

以上,便是我们在拿到原始数据的时候,需要将它进行预处理的全部过程。拿着这份我们预处理后的数据,我们可以知道它的基本描述统计信息,了解在279部豆瓣的热门电影中,平均评分是6.63分等信息。

我叫钟小韦,爱折腾的天府小生,在自我超越的路上,期待与你同行。

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20180528G1MG9L00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券