快乐学Python,DataFrame的基本操作

在上一篇文章中,我们了解了如何使用 pandas 的函数来从多种数据源:csv、excel 和 html 网页。其中不管是哪一种数据读取的方式,最终返回的都是一个 DataFrame 对象。

对于 DataFrame 对象,我们只是简单将其打印出来,这一篇我们来学习围绕 DataFrame 的基本操作(添加行、列,删除行、列,排序等),除了 DataFrame,也会介绍另外一个重要的 pandas 数据结构: Series。

首先介绍 pandas 中的三个最常见的概念:index、Series 和 DataFrame。

1、数据的“目录”: index

index 也叫索引,索引是计算机科学中非常常见的概念,可能听起来会有点陌生,但其实应该很早之前就打过交道了。比如看一本书,书的目录就是书本内容的索引。所以通俗意义上,索引可以理解为就是存储了如何访问某块数据方式的数据。拿目录的例子来说,目录本身也是数据,但这个数据的内容是如何访问另一块数据(书的正文)。

在我们之前的文章中,我们也或多或少和索引打过交道。比如我们通过列表的下标访问列表的某个元素,比如 a[5] ,这个 5 也叫列表的索引。字典的场景中,我们通过 key 来访问字典中的某个元素,比如: student[“name”],这个 “name” 的字符串,也属于字典的索引。

2、一维数据序列:Series

Series 本身是一种数据类型,很像我们之前打过交道的列表,是存储多个数据元素的容器。事实上,我们也可以直接使用一个列表来创建一个 Series。但与列表不同的是,Series 一般由两部分组成:index 和 values。

  • values 容易理解,顾名思义就是存储了 Series 里面的所有元素的值,所以 values 部分可以认为就是和列表是等价的。
  • index 部分代表代表 Series 的索引。根据上面对于索引的定义,index 部分的数据就是为了能方便地定位到 values 里面的数据。

Series 有一个单独的索引项,这就使得它既支持类似列表一样的数字索引,也支持类似字典一样的用字符串或者其他 Python 对象来做索引。对于 Series,可以简单理解成是一个列表和字典的集合体。

接下来用几个实例来简单介绍一下 Series 的概念。

(1)直接从列表创建 Series

import pandas as pd

# 通过列表创建 Series

ser1 = pd.Series([1,3,5,7])

# 通过 notebook 打印 ser1

ser1

输出显示如下:

0    1

1    3

2    5

3    7

dtype: int64

输出有两列,第一列是 index,第二列是 values, values 就是我们传入的列表,而 index 则是对应的序号。当我们只使用列表来创建 Series 对象时,会生成默认的索引。即类似列表那样,每一个元素的位置作为索引。Series 对象也具备 index 和 values 属性,这样我们可以单独访问这两个部分。

print("values: ", ser1.values)

print("index: ", ser1.index)

从以下输出结果可以看到,values 其实就是我们传入的列表,而 index 则是一个 RangeIndex 的对象。

values:  [1 3 5 7]

index:  RangeIndex(start=0, stop=4, step=1)

对于这个 Series 对象,我们可以通过 index 的值来获得对应 values 里面的值。比如 index 等于 1 对应的是 values 里面的 3。在代码中想要获得 1 对应的值就可以这样:

ser1[1]
输出就是:
3

(2)创建 Series,并指定索引

在上面的例子中,我们直接从一个列表创建了 Series,Series 为其分配了默认的 index,即元素在列表中的位置作为其对应的 index,比如 5 是列表 1,3,5,7 中的第三个数字,则它的 index 就是 2(从 0 开始数起)。

除了这种方式,Series 还支持我们在创建的时候指定对应的索引。

# 使用列表创建 Series,并指定其索引为另一个列表

ser2 = pd.Series([1,3,5,7], index=["a""b""c""d"])

# 使用 notebook 打印 ser2

ser2

输出为:

a    1

b    3

c    5

d    7

dtype: int64

可以看到,我们指定了一个由 4 个字符串的列表作为数字列表的索引。两个列表的元素是一一对应的关系,比如字符串 “a” 就是数字 1 的索引,字符串 “b” 就是数字 3 的索引。可以验证一下:

print(ser2["d"])
输出:
7

总结一下, Series 可以看成是高级的列表或者字典,当不指定 index 的时候,Series 会生成默认的位置索引,这样的 Series 就像是一个列表。而当我们指定了 index 之后,则可以通过 index 列表中的元素来访问对应的 values 中的元素,就像字典的 key-value 结构一样。

整体来说,Series 通过将 index 和 values 分别存储的机制,实现了列表和字典的结合

3、二维数据表:DataFrame

看完了 Series,现在我们来看上一篇经常出现的 DataFrame。在上一篇文章中,我们都是从各种文件中加载数据,之后直接存储为 DataFrame。这个部分我们来一步步地揭开 DataFrame 的神秘面纱。

(1)DataFrame 的组成

DataFrame 是一个由行和列组成的二维表格。DataFrame 其实就是由 Series 组成的,DataFrame 的某一行,或者某一列都是一个 Series。

下面我们来实验一下,将上一篇文章生成的tv_rating.csv文件加载到进来读取一下:

# 加载电视剧评分数据

df_rating = pd.read_csv("tv_rating.csv")

# 输出评分的 DataFrame

df_rating

输出为:

快乐学Python,DataFrame的基本操作

在上述表格中,无论是列(比如标题、评分)或者行(比如第二行、第三行)都是 Series。其中 title、rating、stars 则是列的索引。而 0、1、2…9719 是行的索引。

# 获取 rating 这一列,存储在ser_rating 变量中

ser_rating = df_rating["rating"]

# 输出 ser_rating 这个 Series

print(ser_rating)

# 分割一下,方便查看

print("------------分割一下------------")

# 查看数据的类型

print(type(ser_rating))

0       3.7分

1       4.0分

2       4.6分

3       3.4分

4       4.4分

        ... 

3595    4.0分

3596    4.0分

3597    1.0分

3598    2.0分

9719    4.6分

Name: rating, Length: 9719, dtype: object

------------分割一下------------

<class 'pandas.core.series.Series'>

可以看到,分数的这一列被打印出来,格式和上面的 Series 是一样的,左边是 index,右边是 values。之后我们通过 type 函数获得了 ser_rating 变量的类型,确实也是 Series。

除了输出某一列,我们还可以用行索引,来单独输出某一行。比如我们输出第二行:欢喜一家人之加油宝贝,对应的索引是 1。我们可以用如下的代码获取这一行。

# DataFrame 通过 loc 函数可以查看行索引对应的值

# 取出行索引为 1 的行,存储在 ser_1 变量中

ser_1 = df_rating.loc[1]

# 打印 ser1 这个 Series

print(df_rating.loc[1])

# 分割一下,方便查看

print("------------分割一下------------")

# 查看数据的类型

print(type(df_rating.loc[1]))

输出为:快乐学Python,DataFrame的基本操作可以看到,我们拿到的 ser_1 仍然是一个 Series 类型的对象。左边的 title、rating、stars是index,右边的”欢喜一家人之加油宝贝””4.0分” 等是 values。因为 ser_1 是一个 Series,所以如果我们要拿这一行中的某个数据,比如评分,直接写 ser_1[“rating”] 就可以实现。

对比通过行索引取出的行 Series 和 通过列索引取出的列 Series 不难发现,列 Series 的 index 是 DataFrame 的行头,而行 Series 的 index 则是 DataFrame 的列名。

(2)DataFrame 的创建

既然 DataFrame 是一个个 Series 组成的,那自然我们可以用 Series 来构造出 DataFrame。

构造 DataFrame 最常见的方式是用多个行 Series 的形式来创建,不同的行 Series 的长度应该是一致的(因为表格中每一行的元素个数都需要相等)。

# 将列索引保存在 index_arr 变量中

index_arr = ["姓名""年龄""籍贯""部门"]

# 构建小明、小亮、小E的行 Series,并使用我们创建好的 index_arr 作为 Series 的index

ser_xiaoming = pd.Series(["小明", 22, "河北","IT部"], index= index_arr)

ser_xiaoliang = pd.Series(["小亮", 25, "广东","IT部"], index = index_arr)

ser_xiaoe = pd.Series(["小E", 23, "四川","财务部"], index=  index_arr)

# 直接将三个 Series 以列表的形式作为 DataFrame 的参数,创建 DataFrame

df_info = pd.DataFrame([ser_xiaoming, ser_xiaoliang, ser_xiaoe])

# 使用 notebook 打印 DataFrame

df_info

输出:

快乐学Python,DataFrame的基本操作可以看到,表格已经被成功的打印出来,这说明我们已经将内容正确构建出了 DataFrame。

4、基本操作

(1)添加行

DataFrame 提供了 append 的方法,用于添加一行,用法如下:

# 新建一个行 Series,存储在 ser_xiaoh变量中

ser_xiaoh = pd.Series(["小红", 28, "福建""财务部"], index = index_arr)

# 调用 append 方法添加到DataFrame 中

# 设置 ignore_index 的含义是让 DataFrame 自动生成行索引

# 调用 append 之后,会返回一个新的 DataFrame,我们将其保存回 df_info 变量

df_info = df_info.append(ser_xiaoh, ignore_index= True)

# 查看添加后的DataFrame

df_info

输出后可以看到,小红的记录已经追加到了末尾。快乐学Python,DataFrame的基本操作

(2)添加列

添加一列一般有两种情况,如果我们要添加的列,所有行的值都相同的话,我们可以直接以单个值赋值给新添加的列 Series 即可。如下所示:

# 直接将新添加的列名当作 DataFrame 的列索引,对其赋新的值

df_info["考核结果"] = "合格"

# 查看

df_info

输出为:

快乐学Python,DataFrame的基本操作

(3)删除行或列

DataFrame 提供了 drop 方法来删除某一行或者某一列。

我们先以删除列举例,比如要删除刚才我们添加的“考核结果”这一列

# labels 是要删除的列名

# axis = 1 代表要删除的是列

# inplace = True 代表删除直接在 df_info 中生效。

df_info.drop(labels = "考核结果", axis=1, inplace= True)

# 查看

df_info

输出为:

快乐学Python,DataFrame的基本操作接下来是删除行,以删除小 E 这一行为例:

# labels 是要删除行的 index,小E的index是2

# axis = 0 代表要删除的是行

df_info.drop(labels=2, axis=0, inplace=True)

# 查看

df_info

输出结果如下,可以看到,小 E 那一行记录已经被成功删除。

快乐学Python,DataFrame的基本操作

(4)单个单元格的查看与修改

查看单元格:

# loc 属性后面跟中括号,中括号里面第一个元素是行索引,第二个元素是列索引

# 小亮的行索引是1,我们想查看籍贯,所以列索引就是籍贯

df_info.loc[1, "籍贯"]

输出为:

'广东'

学会了查看之后,修改就比较简单了,直接给 loc 属性选出来的单元格赋值即可。

# 对行索引为1,列索引为 籍贯 的单元格赋值,赋值 广西

df_info.loc[1, "籍贯"] = "广西"

# 查看 DataFrame

df_info

输出,可以看到,小亮的籍贯已经被修改为广西。

快乐学Python,DataFrame的基本操作

(5)DataFrame 的排序

在数据分析的任务中,对数据集进行排序是非常常见的诉求。拿我们电视剧评分的数据集来说,可能我们希望分析高分的电影和低分的电影分别都有些什么特征。做这样的分析,首先第一步就是需要将我们的 DataFrame 按评分排序。我们以之前我们从 csv 加载的 DataFrame, df_rating 为例。

DataFrame 提供了 sort_values 方法来实现排序,用法如下。

# by 参数代表要按 rating 这个列索引来排序

# inplace = True 的含义和上面说的一样,代表更新当前的DataFrame,而不是返回一个新的

df_rating.sort_values(by = "rating", inplace=True)

# 查看排序后的 DataFrame

df_rating

输出为:

快乐学Python,DataFrame的基本操作可以看到,整个 DataFrame 不再是按行头的索引排序,而是按照电视剧的评分从低到高来排序了。

如果想看从高到低呢?自然也是支持的。只需要将是否升序排序的参数:ascending 设置为False 即可。

# 在刚才的基础上,增加 ascending=False,代表按降序排序

df_rating.sort_values(by="rating", inplace=True, ascending=False)

# 查看

df_rating

输出为:

快乐学Python,DataFrame的基本操作

(6)取前 N 个和后 N 个

在排序后,我们对数据表要进行分析,比如对高分进行分析,我们往往需要看多几个条目。但是每次输出 DataFrame 的时候,Notebook 一般只会选择前五个和末尾五个组成摘要进行表格的输出。如果默认的表格打印不满足我们的需求,我们可以使用 DataFrame 的 head 函数和 tail 函数来输出前 N 个和 后 N 个的数据。

举个例子,我们希望分别分析 20 条高分电视剧和 20 条低分电视剧。可以按如下方式实现:

# head 函数返回 DataFrame 的前 N 条记录,N就是函数参数指定的值

# 这里我们指定 20 

df_rating.head(20)

输出为:

快乐学Python,DataFrame的基本操作输出最后的 20 条的原理是类似的,只不过换成 tail 函数。

# tail 函数,返回DataFrame 的末尾的 N 条记录,N就是函数的参数

# 这里的N,我们指定 20

df_rating.tail(20)

输出为:

快乐学Python,DataFrame的基本操作

(7)获取 DataFrame 的行数和列数

很多时候,从数据文件加载为 DataFrame 的时候,我们首先会看这个 DataFrame 有多少行、多少列。 DataFrame 提供了 shape 属性来返回行数和列数的信息。

shape 属性返回一个元组,这个数据结构我们之前没有介绍过,不过你可以简单把他当一个列表用即可,shape 属性返回的元组有两个元素,第一个就是行数,第二个就是列数。

比如那 df_rating 这个 DataFrame 为例,打印其行列数信息,代码如下:

# shape 属性,返回一个元祖,第一个是行数,第二个元素是列数

shape = df_rating.shape

# 打印行数和列数

print("行数:", shape[0])

print("列数:", shape[1])

输出为:

快乐学Python,DataFrame的基本操作

更多技术文章欢迎关注:服务端技术精选


原文始发于微信公众号(服务端技术精选):快乐学Python,DataFrame的基本操作

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/258805.html

(0)
服务端技术精选的头像服务端技术精选

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!