相关学习推荐:python教程

这是pandas数据处理专题的第二篇文章,我们一起来聊聊pandas当中最重要的数据结构——DataFrame

上一篇文章当中我们介绍了Series的用法,也提到了Series相当于一个一维的数组,只是pandas为我们封装了许多方便好用的api。而DataFrame可以简单了理解成Series构成的dict,这样就将数据拼接成了二维的表格。并且为我们提供了许多表级别数据处理以及批量数据处理的接口,大大降低了数据处理的难度。

创建DataFrame

DataFrame是一个表格型的数据结构,它拥有两个索引,分别是行索引以及列索引,使得我们可以很方便地获取对应的行以及列。这就大大降低了我们查找数据处理数据的难度。

首先,我们先从最简单的开始,如何创建一个DataFrame。

从字典创建

我们创建了一个dict,它的key是列名,value是一个list,当我们将这个dict传入DataFrame的构造函数的时候,它将会以key作为列名,value作为对应的值为我们创建一个DataFrame。

当我们在jupyter输出的时候,它会自动为我们将DataFrame中的内容以表格的形式展现。

从numpy数据创建

我们也可以从一个numpy的二维数组来创建一个DataFrame,如果我们只是传入numpy的数组而不指定列名的话,那么pandas将会以数字作为索引为我们创建列:

我们在创建的时候为columns这个字段传入一个string的list即可为它指定列名:

从文件读取

pandas另外一个非常强大的功能就是可以从各种格式的文件当中读取数据创建DataFrame,比如像是常用的excel、csv,甚至是数据库也可以。

对于excel、csv、json等这种结构化的数据,pandas提供了专门的api,我们找到对应的api进行使用即可:

如果是一些比较特殊格式的,也没有关系,我们使用read_table,它可以从各种文本文件中读取数据,通过传入分隔符等参数完成创建。比如在上一篇验证PCA降维效果的文章当中,我们从.data格式的文件当中读取了数据。该文件当中列和列之间的分隔符是空格,而不是csv的逗号或者是table符。我们通过传入sep这个参数,指定分隔符就完成了数据的读取。

这个header参数表示文件的哪些行作为数据的列名,默认header=0,也即会将第一行作为列名。如果数据当中不存在列名,需要指定header=None,否则会产生问题。我们很少会出现需要用到多级列名的情况,所以一般情况下最常用的就是取默认值或者是令它等于None。

在所有这些创建DataFrame的方法当中最常用的就是最后一种,从文件读取。因为我们做机器学习或者是参加kaggle当中的一些比赛的时候,往往数据都是现成的,以文件的形式给我们使用,需要我们自己创建数据的情况很少。如果是在实际的工作场景,虽然数据不会存在文件当中,但是也会有一个源头,一般是会存储在一些大数据平台当中,模型从这些平台当中获取训练数据。

所以总体来说,我们很少使用其他创建DataFrame的方法,我们有所了解,着重掌握从文件读取的方法即可。

常用操作

下面介绍一些pandas的常用操作,这些操作是我在没有系统学习pandas的使用方法之前就已经了解的。了解的原因也很简单,因为它们太常用了,可以说是必知必会的常识性内容。

查看数据

我们在jupyter当中执行运行DataFrame的实例会为我们打出DataFrame中所有的数据,如果数据行数过多,则会以省略号的形式省略中间的部分。对于数据量很大的DataFrame,我们一般不会直接这样输出展示,而是会选择展示其中的前几条或者是后几条数据。这里就需要用到两个api。

展示前若干条数据的方法叫做head,它接受一个参数,允许我们制定让它从头开始展示我们指定条数的数据。

既然有展示前面若干条自然也有展示最后若干条的api,这样的api叫做tail。通过它我们可以查看DataFrame最后指定条数的数据:

列的增删改查

前面我们曾经提到过,对于DataFrame而言,它其实相当于Series组合成的dict。既然是dict我们自然可以根据key值获取指定的Series。

DataFrame当中有两种方法获取指定的列,我们可以通过.加列名的方式或者也可以通过dict查找元素的方式来查询:

我们也可以同时读取多列,如果是多列的话,只支持一种方法就是通过dict查询元素的方法。它允许接收传入一个list,可以查找出这个list当中的列对应的数据。返回的结果是这些新的列组成的新DataFrame。

我们可以用del删除一个我们不需要的列:

我们要创建一个新的列也很简单,我们可以像是dict赋值一样,直接为DataFrame赋值即可:

赋值的对象并不是只能是实数,也可以是一个数组:

我们要修改某一列也非常简单,也是通过赋值一样的方法覆盖原数据即可。

转成numpy数组

有时候我们使用pandas不方便,想要获取它对应的原始数据,可以直接使用.values获取DataFrame对应的numpy数组:

由于在DataFrame当中每一列单独一个类型,而转化成numpy的数组之后所有数据共享类型。那么pandas会为所有的列找一个通用类型,这就是为什么经常会得到一个object类型的原因。所以在使用.values之前最好先查看一下类型,保证一下不会因为类型而出错。

总结

在今天的文章当中我们了解了DataFrame与Series的关系,也学习了一些DataFrame的基础和常用的用法。虽然DataFrame可以近似看成是Series组合成的dict,但实际上它作为一个单独的数据结构,也拥有许多自己的api,支持许多花式的操作,是我们处理数据强有力的工具。

有专业机构做过统计,对于一个算法工程师而言,大约70%的时间会被投入在数据的处理上。真正编写模型、调参的时间可能不到20%,从这当中我们可以看到数据处理的必要性和重要程度。在Python领域当中,pandas是数据处理最好用的手术刀和工具箱,希望大家都能将它掌握。

想了解更多编程学习,敬请关注php培训栏目!