Python 教学 | Pandas 妙不可言的条件数据筛选

目录

Part 1  前言

Part 2  Excel 的数据筛选与分布统计

Part 3  Pandas 条件数据筛选

1、条件数据筛选的不同维度

(1) 比较数据值

(2) 是否为空值

(3) 文本内容筛选

(4) 数据值长度

(5) 日期筛选

(6) 其他

2、复合条件筛选

Part 4  总结

Part 5  Python教程


Part 1  前言

在 Python 中,第三方库 Pandas 是数据清洗、处理、分析中的主力工具,几乎所有基于表格数据的需求都能在 Pandas 中得到实现,这也是 Python 语言在数据分析领域独占鳌头的一大因素。在上期技术文章中,我们介绍了 Pandas 中的数据选取功能,这为我们未来批量处理数据打下了良好的基础,本期文章我们将继续介绍 Pandas ,学习处理表格数据十分常用的数据筛选功能。在 Excel / WPS 等 office 软件中,数据筛选经常被使用到,而Pandas 自然也具备数据筛选功能,不仅如此,由于 Pandas 背靠 Python 语言,使得它在字符处理方面具备天然的优势,延伸到数据筛选中来,Pandas 则可以凭借正则表达式对数据进行随心所欲、妙不可言的筛选操作,那么究竟妙在哪里呢?下面我们一起来学习。

本教程基于 pandas 1.5.3 版本书写

本文中所有 Python 代码均在集成开发环境 Visual Studio Code (VScode) 中使用交互式开发环境 Jupyter Notebook 中编写,本文分享的代码请使用 VScode 打开。

点给原文链接即可查看如何获取本文所有演示代码以及演示用的数据:

Python 教学 | Pandas 妙不可言的条件数据筛选

演示数据为 A 股上市公司部分信息(18 个字段,统计时间为 2023年5月12日)

Part 2  Excel 的数据筛选与分布统计

在 Excel / WPS 等办公软件中,最基本的数据筛选主要以单元格的内容为主,以 WPS 为例,选中一列内容后,点击右上方【筛选】,再点击字段名右下方按钮就会弹出按值筛选的筛选框,如下图所示。

这种以字段内容作为条件的数据筛选是最基本、常用的一种,在点击【筛选】后,WPS 会立即对当前字段的所有内容做一个分布统计,显示每一种取值的数量和百分比,因此大家也习惯使用筛选的功能来做字段值的分布统计,说到这里就不得不介绍一下 Pandas 中的字段值统计操作了,下面是读取数据并统计上市地点字段值分布的代码。

读取并展示部分数据:

# 导入 pandas
import pandas as pd
# 读取演示数据
data = pd.read_excel('./A股上市公司部分信息(截至2023.5.12).xlsx')
# 处理字段名,做简化处理
data.columns = [COL.split('n')[0] for COL in list(data.columns)]
# 展示数据前两行
data.head(2)

字段取值数量统计:统计上市地点字段中值的分布

# 数量统计
data['上市地点'].value_counts()
# 所得结果如下图,A股上市公司上市地点中,值为“深圳”的最多,为 2771

字段取值比率统计:统计上市地点字段中值的分布,以比率的形式展现

# 比率统计,在数量统计的基础上加一个参数 normalize=True
data['上市地点'].value_counts(normalize=True)

除此之外,如果需要对字段内容进行片段内容查询,还可以在上图所示的筛选框中点击右上方的【文本筛选】进行更细致的筛选。除了查找明确的字符,还可以使用通配符*?进行模糊匹配(*代表任意多个字符,?代表任意单个字符),颇有一些正则表达式的味道。

在 Pandas 中,类似的数据筛选同样存在,不仅如此,在模糊查找方面,由于 Pandas 中已经融入了正则表达式,所以在文本数据的筛选中,可以利用正则表达式进行更加自由、细致的筛选操作,除此之外,Pandas 还可以从更多的维度来进行筛选,下面我们一起来学习。

在 Pandas 中,类似的数据筛选同样存在,不仅如此,在模糊查找方面,由于 Pandas 中已经融入了正则表达式,所以在文本数据的筛选中,可以利用正则表达式进行更加自由、细致的筛选操作,除此之外,Pandas 还可以从更多的维度来进行筛选,下面我们一起来学习。

本文拿 Excel / WPS 与 Pandas 做了数据筛选方面的简单对比,本意不是踩一捧一,而是说明不同工具的差异。如果大家能在这里学到 Excel / WPS 的实用操作,这当然也是一件好事。

Part 3  Pandas 条件数据筛选

在上一期介绍数据选取文章中,我们介绍了使用loc函数进行简单条件筛选的功能。实际上除了loc函数,Pandas 中还有几个可以用来数据筛选的函数或形式,比如query函数、切片([])等。在这些函数中,笔者认为通用性最佳的方式是使用切片([])来做数据筛选。切片筛选的形式如下。

变量名[<条件表达式>]

如何使用切片来做数据筛选呢?下面我们以上一节读取的数据data为例,从不同的维度的筛选条件做介绍。

1、条件数据筛选的不同维度

(1) 比较数据值

一种最简单,但又最常见的数据筛选条件就是通过判断一个字段的值是否等于、不等于指定的值。例如当我们想筛选上市地点在北京的A股上市公司数据,可以使用下面的筛选代码。

# 筛选上市地点在北京的A股上市公司数据
data[data['上市地点'] == '北京']

代码中的data['上市地点'] == '北京'就是筛选的条件,筛选结果(部分)如下图所示。

如果想获取data中不是在北京上市的企业,那么筛选条件就是上市地点不等于“北京”,编写代码时只需将上述代码中的等于号==改成不等于号!=即可,这里不再具体演示。

当情况比较多的时候,例如筛选出城市字段是北京市、上海市、广州市、深圳市其中一种的数据时,可以使用的方法不止一种,下面是其中一种方法的代码。

# 筛选出城市字段是北京市、上海市、广州市、深圳市其中一种的数据
data[data['城市'].isin(['北京市', '上海市', '广州市', '深圳市'])]

上面两个案例是根据内容为文本的字段进行筛选,如果需要对一个数字字段做筛选,我们还可以使用 Python 中的其他比较运算符来做筛选,举个例子,当需要筛选员工总数大于等于 10000 的A股上市企业时,可以使用下面的代码。

# 筛选员工总数大于等于 10000 的企业
data[data['员工总数'] >= 10000]

同理,还可以使用大于、小于、小于等于等比较运算符来做数据筛选。这些比较数据值大小的筛选条件中,除了能拿字段和常量做比较,还可以拿字段和字段作比较,例如我们可以筛选出员工总数大于等于所属行政区划代码的数据(当然这个条件没有任何实际意义,这里只是举一个例子),可以使用下面的代码。

# 先将 所属行政区划代码 字段类型转为数字型
data['所属行政区划代码'] = data['所属行政区划代码'].astype(int)
# 筛选出员工总数大于等于所属行政区划代码的数据
data[data['员工总数'] >= data['所属行政区划代码']]

(2) 是否为空值

有些时候,我们需要根据某个字段的值是否为空值来做筛选,比如筛选数据data所属上市标准字段值不为空的数据,可以使用下面的代码。

# 筛选所属上市标准字段值不为空的数据
data[data['所属上市标准'].notna()]

如果需要获取某字段值为空的数据,可以将上述代码中的notna()替换为isna()即可。

Python 中默认的空值是 None,在 Pandas 中,表格数据中默认的空值(或者说缺失值)是 NaN,它是 numpy 库中的常量,意为 Not a Number,由于 Pandas 是以 numpy 库为基础开发的,故在表格数据中保留此设定,将空值设置为 NaN(numpy.nan)。而isna()notna() 函数能够识别的空值也包括 None 和 NaN,但不包括空字符'',即空字符''在 pandas 中不属于空值。

(3) 文本内容筛选

正如介绍 Excel / WPS 时说的那样,这类办公软件可以对某个字段做文本筛选,筛选字段中包含、不包含、开头(不)是、结尾(不)是某关键词的数据,除此之外还可使使用一些通配符来做模糊筛选。这种筛选操作在  Excel 中已经很强大了,但是这些在拥有正则表达式加持的 Pandas 面前,都算是小菜一碟。下面我们来介绍一下 Pandas 如何根据字段中的文本内容进行筛选数据。

首先,最简单的条件就是字段中是否包含(或不包含)某关键词,例如筛选数据data公司中文名称字段含有关键词“证券”的企业,可以使用下面的数据筛选代码。

# 筛选数据中 公司中文名称 字段含有关键词“证券”的企业
data[data['公司中文名称'].str.contains('证券')]
# 筛选后得到 41 条符合条件的数据

如果希望筛选出所有公司中文名称不含关键词“证券”的数据,则可以在上面代码的条件表达式最前面加一个波浪符~,代码如下(不再展示筛选结果)。

# 筛选数据中 公司中文名称 字段不含关键词“证券”的企业
data[~data['公司中文名称'].str.contains('证券')]

除了以上这种最基本的关键词筛选之外,其他的像 Excel 那种根据文本的开头或结尾进行筛选的操作,在 Pandas 都可以通过正则表达式来实现,那么如何在 Pandas 的数据筛选中使用正则表达式呢?很简单,以上述代码为例,只需要将正则表达式传入contains函数,取代关键词即可。例如筛选公司中文名称段中含有“证券”,“银行”或“保险” 的数据时,就可以使用正则表达式进行处理,代码如下。

正则表达式教程已经更新完毕,请到文末查找相关链接

# 筛选公司中文名称字段中含有“证券”,“银行”或“保险” 的数据
data[data['公司中文名称'].str.contains('证券|银行|保险')]

除此之外,我们还可以使用更加复杂的正则表达式进行更加复杂的筛选操作,例如筛选注册地址字段中不含有中文的数据可以使用下面的代码来实现。

# 筛选 注册地址 字段中不含有中文的数据
data[~data['注册地址'].str.contains('[u4e00-u9fa5]')]

根据文本内容做筛选时,有一点需要特别注意,那就是进行筛选的字段中,必须所有值都是字符类型,不能是空值(若含有空值,可先填充缺失值为字符型),不能包含数字型和日期型,因为正则表达式无法对这些类型做处理。

(4) 数据值长度

有时候字段中文本的长度也能反映出一些信息,例如注册地址中字符数量越多,说明地址的描述越详细,而Pandas 则可以根据字符的长度做筛选,例如当需要筛选注册地址字段中字符数量小于等于 10 的所有数据时,可以使用下面的代码。

# 筛选注册地址字段中字符数量小于等于 10 的所有数据
data[data['注册地址'].str.len() < 10]

(5) 日期筛选

除了对数值和字符进行筛选,Pandas 也能像 Excel 那样根据日期筛选数据,例如筛选 2023 年新上市的A股企业,就可以使用下面的代码。

# 先将 上市日期 字段转为 python 中的日期类型
data['上市日期'] = data['上市日期'].astype('datetime64[ns]')
# 筛选 2023 年新上市的A股企业
data[data['上市日期'] >= pd.Timestamp(2023, 1, 1)]

(6) 其他

除了以上介绍的数据筛选维度,Pandas 的数据筛选还可以有其他的维度,比如根据索引值、字段名筛选,不过这些知识点的实用性算不上高,这就不过多介绍了。

2、复合条件筛选

大家可能已经注意到,上文介绍的数据筛选虽然维度不同,但是所有的筛选案例中都只有一个筛选条件。实际上 Pandas 的数据筛选是可以存在多个筛选条件(两个及两个以上)的。当存在多个条件时,每个条件最好都使用括号括起来,如果其中两个条件时是“或”关系,那么使用逻辑或符号|来连接它们;如果两个条件的关系是“与”关系,那么就要用逻辑与符号&来连接它们。在 Pandas 中,上文中介绍的所有条件形式都可以进行任意的排列组合。下面我们通过几个例子来了解如何进行复合条件筛选。

【例 1】筛选出A股上市公司数据中,所属行政区划位于“江浙沪”,且员工总数大于等于 20000 的数据。

## 【例 1】筛选出A股上市公司数据中,所属行政区划位于“江浙沪”,且员工总数大于等于 20000 的数据。
# 为了方便查看,在代码中加了几个不必要的空格
data[ (data['所属行政区划'].isin(['上海', '江苏省', '浙江省'])) & (data['员工总数'] >= 20000) ]

【例 2】筛选出企业规模为大型,或注册资本大于等于 10 亿的企业数据。

## 【例 2】筛选出企业规模为大型,或注册资本大于等于 10 亿的企业数据。
data[(data['企业规模']=='大型') | (data['注册资本'] > 1000000000)]

以上就是 Pandas 条件数据筛选的内容。

Part 4  总结

与 Excel / WPS 等办公软件一样,Pandas 也具备多种形式的条件筛选。不仅如此,得益于正则表达式强大的文本处理力量,Pandas 在筛选功能方面要更加强大,对大数据集的支持也要更好。相对而言 Excel / WPS 这些工具在小型数据集的处理上要方便一些,总之它们各有长处。条件数据筛选是数据处理、数据分析中的重要一步,希望大家学习路上一帆风顺,下期文章我们将继续学习 Pandas 数据处理相关知识。

Part 5  Python教程