Python 教学 | 数据处理必备工具之 Pandas(基础篇)
四、Pandas的字段类型五、总结Python教程
全文共7725个字,阅读约需20分钟,欢迎指正!
Part1引言
Python 自带的标准库能够解决一部分数据处理的任务,但面对大规模且复杂的数据集,我们往往就需要借助 Python 第三方库来实现。举个例子,如果我们需要通过 Python 程序进行一些数学运算,标准库中的 math 库就可以胜任,但是当我们面对的是一个包含多种数据类型的大规模数据集时,就需要用更多的数据结构和数据操作方法来处理该数据集,此时 Python 中的第三方库 Pandas 的实用价值就凸显出来了,作为 Python 数据处理和数据分析中最重要的库(没有之一),它的功能非常强大,不仅可以用于数据处理,还可以对数据进行统计分析和可视化。在数据处理方面,Pandas 提供了许多实用的功能,比如可以使用 Pandas 从 csv、Excel、数据库等多种数据源中读取数据,除此以外,Pandas 的数据处理非常完备,下面列举了常用的几个功能:
合并多个文件的数据,或者将数据拆分为多个独立文件 建立高效的索引,灵活地查询、筛选数据 对数据进行去重、填充、删除、替换、转换等操作
...
当然,Pandas 的功能远不止这些。可以说,掌握了 Pandas 能够让我们在数据处理和数据分析中如虎添翼,Pandas 有这么多的功能,要从何学起呢?我们基于这个出发点推出了 Pandas 教学系列文章,旨在从浅入深地介绍 Pandas 在数据处理中的应用,让你体验大数据处理的魔力。本期文章主要介绍了 Pandas 的数据结构和数据类型,作为入门 Pandas 的第一期,这也是十分重要的。
本教程基于 pandas 1.5.3 版本书写 本文中所有 Python 代码均在集成开发环境 Visual Studio Code (VScode) 中使用交互式开发环境 Jupyter Notebook 中编写
Part2Pandas 的由来
正式学习 Pandas 之前,笔者想先介绍一下 Pandas 库的由来。一说到 Pandas 这个词,我们第一个想到的应该就是国宝“熊猫”,但是实际上 Pandas 和熊猫无关,它来自于计量经济学中的术语“面板数据”(Panel data)。
Pandas 是由 Wes McKinney 在 2008 年开发的,McKinney 当时是一家纽约金融服务机构的金融分析师 ,他在自己的工作中遇到了一些数据操作问题,当时 Python 中已经有了 Numpy 这样在处理大规模数据方面有着不错表现的库,但是对于表格等结构化数据而言,Numpy 并不能完全胜任。于是 McKinney 开始着手研究一套解决方案,目的是为了在 Python 中提供一种更便捷的方式来处理结构化数据,最终 Pandas 就被开发出来了。
刚才我们提到了 Python 中的 Numpy 库,这个库的主要用途是以数组的形式进行数据操作和数学运算。实际上 Pandas 是以 Numpy 为基础设计的,Pandas 中 DataFrame 和 Series(下文介绍)这两种数据结构是利用了 Numpy 数组作为底层结构的,这也使得 Pandas 数据处理更加高效,同时基于这种数据结构,Pandas 也为 Numpy 的不足之处进行了一些改进,Pandas 比 Numpy 支持更多的数据类型,在数据处理中更加灵活。虽然 Pandas 是依赖于 Numpy 的,但是这不意味着必须要先掌握 Numpy 的功能,我们直接使用 Pandas 即可,在学习过程中有需要再补充相关内容。
Part3Pandas 的数据结构
在介绍 Pandas 的数据结构之前,首先需要了解什么是数据结构。数据结构指的是组织数据、储存数据的方式,数据结构的选择直接影响了数据的处理效率和数据操作的灵活性。
我们日常接触最多的结构是数组(类似于序列),数组是由相同类型元素的集合组成,对每一个元素分配一个存储空间,并且每个空间会有一个索引(下文介绍)来标识元素的存储位置,我们可以通过索引来访问元素。实际数据往往是由多个数组组成,它们共用同一个行索引,组成了一个二维数组,这类似于 Excel 表格中用字母表示一列,用数字表示行号,这样就可以确定元素的具体位置。
💡数组中的元素可以是任何类型的数据,包括整数型、浮点数型、布尔型等等。但是数组中所有元素的数据类型必须是一致的(在 Numpy 中,通常是将类型强制转换为一致的类型后进行存储),这是因为数组需要先为所有元素在内存中分配相同的空间大小,以保证数据存储的连续性和高效性。
Pandas 提供了 Series 和 DataFrame 作为数组数据的存储框架,当数据以这两种结构存储后,我们就可以利用它们提供的强大功能对数据进行处理。下面具体来看这两种数据结构。
1什么是 Series
Series 是 Pandas 最基础的数据结构。通俗来说,Series 是一种类似于一维数组的数据结构,其中每个元素都带有一个标签(下文统称为“索引”),下面我们来看一个简单的 Series。
import pandas as pd # 导入 pandas 模块,约定俗成,起别名为 pd
# 创建一个 Series,并且自定义数据索引
pd.Series([4010.4, 2318.02, 3873.16], index=['北京', '天津', '河北'])
在 Pandas 中使用pd.Series()
函数来创建 Series,其中的参数index
用于自定义数据的索引。创建的 Series 结果如下。
这个 Series 是 2019 年地区的采矿业的资产总计,第一列是 Series 的索引,它起到解释、定位数据的作用(如果不指定索引,默认从 0 开始编号),第二列是 Series 的值,最后一行dtype:float64
表明该 Series 的类型统一为float64
,表示占用 64 位(8字节)内存空间的双精度小数。
除了使用参数index
,我们还可以使用字典直接创建带有自定义索引的数据,Pandas 会将字典的键作为索引,值作为对应的数据,得到的结果和上图一样,代码如下。
pd.Series({'北京':4010.4, '天津':2318.02, '河北':3873.16})
如果我们想要访问 Series 中的数据呢?这一点很简单,类似于 Python 中访问列表和字典元素的方式,只需要使用中括号加数据索引([数据索引]
)就可以实现,比如我们想要查看 2019 年河北省的资产总计,实现的代码如下。
# 将创建的 Series 赋值给变量 Value
Value = pd.Series({'北京':4010.4, '天津':2318.02, '河北':3873.16})
Value['河北'] # 输出:3873.16
可以看到无论是创建一个 Series 还是访问其中的元素时,都使用到了索引(index),实际在 Pandas 中索引是一个很重要的工具,索引相当于是一本书的书签,可以帮助我们快速找到想要查看的内容,通过索引我们不仅可以快速定位数据,还可以从 DataFrame 中选择特定的行数和列数等等。但是需要注意一点,在不同的场景中索引可能被称为其他名称,需要灵活理解和掌握,比如在二维数据结构中有行索引和列索引,行索引通常指的是每一行的索引,而列索引也被称为字段名、表头等。
2什么是 DataFrame
实际中的数据大多是以二维表的形式存在的,类似于 Excel 的表格数据。在 Pandas 中二维数据是存储在 DataFrame 数据结构中的,换句话说,DataFrame(也称为“数据框”)其实就是一个m行 × n列
的二维数据,下面我们创建一个 DataFrame,具体来看一下它的结构。
# 创建一个5行、5列的 DataFrame,赋值给变量 Data
data_list = [['110000','北京', 4010.4, 707.21, 1057.87],
['120000', '天津', 2318.02, 1423.45, 4051.2],
['130000', '河北', 3873.16, 1073.04, 2676.77],
['140000', '山西', 26229.57, 5951.44, 10415.53],
['150000', '内蒙古', 9945.73, 3029.35, 5764.29]]
Data = pd.DataFrame(data_list, columns=['省份代码', '省份名称', '资产总计', '固定资产净额', '固定资产原价'])
Data # 查看结果
结果如下:
在 Pandas 中使用pd.DataFrame()
函数来创建 DataFrame,我们在上面的代码中通过参数columns
来指定数据框的列索引(也称为“字段名”或“列名”),上图最左侧一列为 Data 的行索引,默认是从 0 开始的自然数,也可以通过pd.DataFrame()
函数中的参数index
自定义索引值。
同时,在创建 Data 时我们使用的是一个列表 data_list,不难发现,这个嵌套列表中每一个子列表为 DataFrame 的一行,这和创建 Series 时类似,实际上 DataFrame 的每一行或者每一列都可以看作一个 Series,比如我们想查看“省份名称”这列数据,只需要通过代码Data[字段名]
就可以实现,结果如下。
Data['省份名称']
可以看到这就是一个由索引和对应数据构成的 Series,并且这个Series 使用的索引是 DataFrame 的行索引,所以 DataFrame 本质上可以看作由多个一维 Series 构成的二维数据,两者的关系可以通过下图来理解。
同理,DataFrame 的每一行也可以被视作一个 Series,这个 Series 的索引就是 DataFrame 的列索引(字段名)。示例如下。
Data.loc[2] # 得到 Data 的第二行
现在我们已经对 DataFrame 的结构有了初步的了解,下面再来看看创建 DataFrame 的方法。在 Pandas 中构建 DataFrame 的方法有很多,除了使用嵌套列表(多维列表),我们也经常使用字典来创建 DataFrame,使用字典生成本节中的 DataFrame 的代码如下。
# 使用字典创建一个 DataFrame
data_dict = {
'省份代码':['110000', '120000', '130000', '140000', '150000'],
'省份名称':['北京','天津','河北','山西','内蒙古'],
'资产总计':[4010.4, 2318.02, 3873.16, 26229.57, 9945.73],
'固定资产净额':[707.21, 1423.45, 1073.04, 5951.44, 3029.35],
'固定资产原价':[1057.87, 4051.2, 2676.77, 10415.53, 5764.29]
}
# 传入等长列表组成的字典
Data = pd.DataFrame(data_dict)
# 查看结果
Data
在这个代码中,我们将一个等长列表组成的字典传入pd.DataFrame()
函数中,字典的键会作为 DataFrame 的列索引,字典的值为对应每一列的数据,这里我们是以列表作为字典的值,实际中也可以使用其他方式生成字典的值。需要注意一点,字典的每个值长度必须相等,否则无法成功创建 DataFrame。
Part4Pandas 的字段类型
了解 Pandas 中的数据类型是必要的,这是因为在实际数据处理过程中,我们通常需要从多种数据源读取数据、并对数据进行合并等操作。我们应该知道 Excel 中每个单元格都有自己的数据类型(比如数值、文本、日期等等),相同的是 Pandas 数据结构中的每一个元素也有自身的数据类型,除此以外,Pandas 中每一个字段也具有类型属性,即字段类型,字段类型就是 Pandas 数据结构中一列的数据类型,也可以通俗理解为一列中所有数据的共性,Pandas 常见的字段数据类型如下表。
DataFrame 字段类型 |
---|
float64 |
int64 |
bool |
datatime64 |
timedelta[ns] |
object |
何时使用上表的字段类型呢?如果 Pandas 中一列数据都是浮点数,那么这一列的字段类型就为float64
,如果一列数据全部都是整数,那么这一列的字段类型就是int64
,同理,bool
、datatime64
和timedelta[ns]
也是如此。
除了上面提到的五种常见的字段类型,Pandas 中还有一个特殊的字段类型:object
。如果 Pandas 中一列的数据都是字符型或者这一列中除了数值型数据还存在一种或多种数据类型时,该列的字段类型就为object
,仅通过这一句话你可能并不清楚这个数据类型的作用,为了更清楚地了解object
这个类型,我们先输出上一章创建的 DataFrame 的数据类型,查看各字段类型的代码如下。
# pandas中使用.dtypes这个属性查看 DataFrame 每一列的数据类型
Data.dtypes
从上图可以看到,“省份代码”和“省份名称”这两列的字段类型均为object
(根据创建 DataFrame 的代码,这两列数据值均为字符型),另外三列字段类型为float64
(根据创建 DataFrame 的代码,这三列的数据均为浮点型)。现在我们对该 DataFrame 进行一些修改,代码如下。
# 导入 numpy库,使用 np.NaN 表示缺失值
import numpy as np
## “省份代码”中既有整型,也有字符型
## “资产总计”中既有浮点型,也有bool型
## “固定资产净额”中既有缺失值NaN,又有整型和浮点型
data_dict = {
'省份代码':[110000, 120000, 130000, 140000, '150000'],
'省份名称':['北京','天津','河北','山西','内蒙古'],
'资产总计':[True, 2318.02, 3873.16, 26229.57, 9945.73],
'固定资产净额':[np.NaN, 1423, 1073.04, 5951.44, 3029.35],
'固定资产原价':[1057.87, 4051.2, 2676.77, 10415.53, 5764.29]
}
Data = pd.DataFrame(data_dict)
Data
在上面的代码中,我们使用np.NaN
表示缺失值,这是由于 Pandas 是基于 Numpy 开发的,所以 Pandas 表格中的缺失值默认是使用 Numpy 库的常量np.NaN
来表示,np.NaN
表示缺失值(NaN 即"Not a number"
,也就是数值无法精确表示或者不存在的值),它是一个特殊的浮点数。
更改后的 DataFrame 的数据类型如下。
从结果来看,更改 DataFrame 前后的字段类型发生改变了,实际上 Pandas 已经对数据类型自动进行转换了,下面是更改后的数据集:
根据上面的两个结果,我们具体来看发生更改的列的情况:第一,对于包含整型、浮点型和 np.NaN 的“固定资产净额”列,当整型和浮点型同时存在一列中时,Pandas 会自动将整数型转换为浮点型(如整数1423
转换为浮点数1423.00
),此时该列的字段类型为float64
(在 Pandas 中,np.NaN的数据类型为float
);第二,从“省份代码”或“资产总计”列可以看到,当一列中出现了字符型、bool型的数据时,Pandas 指定该列的字段类型为object
。结合以上两点,总结上面出现的 Pandas 的数据类型转换规则如下:
当缺失值 np.NaN
、整型与浮点型三种数据中任意两种及两种以上共存于一列时,该列的字段类型就会转换为float64
。如果一列中存在字符型或者同时存在两种及两种以上数据类型时(整型与 np.NaN
或浮点型共存于一列时,视为只有浮点型这一种数据类型),该列的字段类型就会转换为object
。
通过上面这个例子,我们已经较为全面地了解了object
这个字段类型,但是关于 object 类型我们需要注意一点,当我们在数据处理中需要进行数据合并等操作时,为了避免由于数据类型不一致导致的错误,我们建议大家在使用 Pandas 从csv/Excel 等其他数据源读取数据后,要注意数据类型的一致性问题,通过 Pandas 提供的数据类型转换方法(后续介绍),确保 Series 或 DataFrame 数据类型保持一致。
了解 Pandas 字段类型有什么作用呢?掌握常见的字段类型能够有助于我们检查数据中的错误或者缺失情况,实际中我们的数据通常会以列为单位,即一列的值是同一种数据类型,当我们使用 Pandas 读入数据后,可以通过dtypes
属性检查一列数据的字段类型,比如一列数据均为数值型,那么该列的字段类型应该为int64/float64
,如果该列的字段类型为object
时,说明该列中可能出现了类型不一致的数值,此时需要检查并校正数据,这样能够保证我们在进行数据处理或分析之前数据的准确性。
Part5总结
如果你想要在数据处理和分析时更加高效方便,那么 Pandas 库是必不可少的,本文作为 Pandas 教程的第一期文章,内容介绍更侧重于 Pandas 基础,如果你认真读完本文,应该已经掌握了 Pandas 中两个数据结构 Series 和 DataFrame 以及 Pandas 的字段类型,尤其是 object 数据类型,这也是数据处理和分析需要注意的地方。Pandas 中的 DataFrame 结构具有很强大的兼容性,本文中使用的 DataFrame 是通过代码创建的,此外我们还可以将本地存储的 csv/Excel 文件或其他数据源的表读取为 DataFrame,读取数据源文件是数据处理和分析的第一步,但是 Pandas 提供了多种读取数据源的方法,这其中涉及到的内容并非三言两语能够介绍清楚的,下一期文章中,我们将详细介绍使用 Pandas 读取数据源的方法,下期再见。
Part6Python教程
学习 Python 第一步——环境安装与配置 Python 基本数据类型 Python 字符串操作(上) Python 字符串操作(下) Python 变量与基本运算 组合数据类型-列表 组合数据类型-集合(内含实例) 组合数据类型 - 字典&元组 Python 中的分支结构(判断语句) Python 中的循环结构(上) Python 中的循环结构(下) Python教学 | Python函数的定义与调用 Python教学 | Python 内置函数 Python教学 | 最常用的标准库之一 —— os Python 教学 | “小白”友好型正则表达式教学(一) Python 教学 | “小白”友好型正则表达式教学(二) Python 教学 | “小白”友好型正则表达式教学(三) 本期 持续更新中……
星标⭐我们不迷路!想要文章及时到,文末“在看”少不了!
点击搜索你感兴趣的内容吧
往期推荐
数据Seminar
这里是大数据、分析技术与学术研究的三叉路口
文 |《社科领域大数据治理实务手册》
欢迎扫描👇二维码添加关注