Pandas的数据过滤实现


Posted in Python onJanuary 15, 2021

作者|Amanda Iglesias Moreno 编译|VK 来源|Towards Datas Science

从数据帧中过滤数据是清理数据时最常见的操作之一。Pandas提供了一系列根据行和列的位置和标签选择数据的方法。此外,Pandas还允许你根据列类型获取数据子集,并使用布尔索引筛选行。

在本文中,我们将介绍从Pandas数据框中选择数据子集的最常见操作:

  • 按标签选择单列
  • 按标签选择多列
  • 按数据类型选择列
  • 按标签选择一行
  • 按标签选择多行
  • 按位置选择一行
  • 按位置选择多行
  • 同时选择行和列
  • 选择标量值
  • 使用布尔选择选择选择行

数据集

在本文中,我们使用一个小数据集进行学习。在现实世界中,所使用的数据集要大得多;然而,用于过滤数据的过程保持不变。

数据框包含公司10名员工的信息:(1)身份证,(2)姓名,(3)姓氏,(4)部门,(5)电话,(6)工资,(7)合同类型。

import pandas as pd

# 员工的信息
id_number = ['128', '478', '257', '299', '175', '328', '099', '457', '144', '222']
name = ['Patrick', 'Amanda', 'Antonella', 'Eduard', 'John', 'Alejandra', 'Layton', 'Melanie', 'David', 'Lewis']
surname = ['Miller', 'Torres', 'Brown', 'Iglesias', 'Wright', 'Campos', 'Platt', 'Cavill', 'Lange', 'Bellow']
division = ['Sales', 'IT', 'IT', 'Sales', 'Marketing', 'Engineering', 'Engineering', 'Sales', 'Engineering', 'Sales']
salary = [30000, 54000, 80000, 79000, 15000, 18000, 30000, 35000, 45000, 30500]
telephone = ['7366578', '7366444', '7366120', '7366574', '7366113', '7366117', '7366777', '7366579', '7366441', '7366440']
type_contract = ['permanent', 'temporary', 'temporary', 'permanent', 'internship', 'internship', 'permanent', 'temporary', 'permanent', 'permanent']

# 包含员工信息的dataframe
df_employees = pd.DataFrame({'name': name, 'surname': surname, 'division': division,
               'salary': salary, 'telephone': telephone, 'type_contract': type_contract}, index=id_number)

df_employees

Pandas的数据过滤实现

1.按标签选择单列

要在Pandas中选择一个列,我们可以使用.运算符和[]运算符。

按标签选择单列

df[string]

下面的代码使用这两种方法访问salary列。

# 使用.符号选择列(salary)
salary = df_employees.salary

# 使用方括号选择列(salary)
salary_2 = df_employees['salary']

# 当选择单个列时,我们获得一个Series对象
print(type(salary))
# <class 'pandas.core.series.Series'>

print(type(salary_2))
# <class 'pandas.core.series.Series'>

salary

Pandas的数据过滤实现

如上所示,当检索单个列时,结果是一个Series对象。为了在只选择一列时获得一个DataFrame对象,我们需要传入一个列表,而不仅仅是一个字符串。

# 通过向索引操作符传递一个字符串来获取一个Series对象
df_employees['salary']

# 通过将带有单个项的列表传递给索引操作符来获取DataFrame对象
df_employees[['salary']]

Pandas的数据过滤实现

此外,重要的是要记住,当列名包含空格时,我们不能使用.表示法来访问数据帧的特定列。如果我们这么做了,就会产生一个语法错误。

2.按标签选择多列

我们可以通过传入一个列名称如下的列表来选择一个数据帧的多个列。

按标签选择多列

df[list_of_strings]
# 通过将包含列名的列表传递给索引操作符来选择多个列
df_employees[['division', 'salary']]

Pandas的数据过滤实现

如上所示,结果是一个DataFrame对象,只包含列表中提供的列。

3.按数据类型选择列

我们可以使用pandas.DataFrame.select类型(include=None,exclude=None)根据列的数据类型选择列。该方法接受参数include和exclude中的列表或单个数据类型。

请记住,必须至少提供其中一个参数(include或exclude),并且它们不能包含重叠的元素。

按数据类型选择列

df.select_dtypes(include=None, exclude=None)

在下面的示例中,我们通过传入np.number对象添加到include参数。或者,我们可以通过提供字符串'number'作为输入来获得相同的结果。

可以看到,select_dtypes()方法返回一个DataFrame对象,该对象包括include参数中的数据类型,而排除exclude参数中的数据类型。

import numpy as np

# 选择数值列- numpy对象
numeric_inputs = df_employees.select_dtypes(include=np.number)

# 使用.columns属性
numeric_inputs.columns
# Index(['salary'], dtype='object')

# 该方法返回一个DataFrame对象
print(type(numeric_inputs))
# <class 'pandas.core.frame.DataFrame'>

# 选择数字列
numeric_inputs_2 = df_employees.select_dtypes(include='number')

# 使用.columns属性
numeric_inputs_2.columns
# Index(['salary'], dtype='object')

# 该方法返回一个DataFrame对象
print(type(numeric_inputs_2))
# <class 'pandas.core.frame.DataFrame'>

# 可视化数据框
numeric_inputs

Pandas的数据过滤实现

如前所述,select_dtypes()方法可以同时接受字符串和numpy对象作为输入。下表显示了在Pandas中引用数据类型的最常用方法。

Pandas的数据过滤实现

作为提醒,我们可以使用pandas.DataFrame.info方法或使用pandas.DataFrame.dtypes属性。前者打印数据帧的简明摘要,包括列名及其数据类型,而后者返回一个包含每个列的数据类型的序列。

# 数据框架的简要摘要,包括列名及其数据类型
df_employees.info()

Pandas的数据过滤实现

# 检查列的数据类型
df_employees.dtypes

Pandas的数据过滤实现

4.按标签选择单行

数据帧和序列不一定有数字索引。默认情况下,索引是表示行位置的整数;但是,它也可以是字母数字字符串。在我们当前的示例中,索引是员工的id号。

# 我们可以使用.index方法检查数据帧的索引
df_employees.index
# Index(['128', '478', '257', '299', '175', '328', '099', '457', '144', '222'], dtype='object')
# 索引是雇员的id号。

要按id号选择一行,我们可以使用.loc[]索引器提供一个字符串(索引名)作为输入。

按标签选择单行

df.loc[string]

下面的代码显示如何选择id号为478的员工。

# 使用.loc[]索引器选择id号为478的员工
df_employees.loc['478']

Pandas的数据过滤实现

如上所示,当选中一行时,.loc[]索引器将返回一个Series对象。但是,我们也可以通过将单个元素列表传递给.loc[]方法来获得单行数据帧,如下所示。

# 使用.loc[]索引器选择id号为478的雇员,并提供一个单元素列表
df_employees.loc[['478']]

Pandas的数据过滤实现

5.按标签选择多行

我们可以使用.loc[]索引器选择多行。除单个标签外,索引器还接受一个列表或标签片段作为输入。

按标签选择多行

df.loc[list_of_strings]
df.loc[slice_of_strings]

接下来,我们获得包含id号为478和222的雇员的数据帧的子集,如下所示。

# 使用.loc[]索引器选择id号为478和222的员工
df_employees.loc[['478', '222']]

Pandas的数据过滤实现

请注意,始终包含.loc[]方法的结束索引,这意味着所选内容包括最后一个标签。

6.按位置选择单行

iloc[]索引器用于按位置索引数据帧。要使用.iloc[]属性选择单行,我们将行位置(单个整数)传递给索引器。

按位置选择单行

df.iloc[integer]

在下面的代码块中,我们选择索引为0的行。在这种情况下,返回数据帧的第一行,因为在Pandas中索引从0开始。

# 选择数据帧的第一行
df_employees.iloc[0]

Pandas的数据过滤实现

此外,.iloc[]索引器还支持负整数(从-1开始)作为相对于数据帧末尾的相对位置。

# 选择数据帧的最后一行
df_employees.iloc[-1]

Pandas的数据过滤实现

如上所示,当选择一行时,.iloc[]索引器返回一个以列名作为索引的Series对象。但是,正如我们对.loc[]索引器所做的那样,我们还可以通过以下方式将单个整数列表传递给索引器来获取数据帧。

# 选择数据帧的最后一行
df_employees.iloc[[-1]]

Pandas的数据过滤实现

最后,请记住,在尝试访问超出边界的索引时会引发索引器错误。

# 数据框的形状- 10行6列
df_employees.shape
# (10, 6)

# 当试图访问一个越界的索引时,会引发一个IndexError
df_employees.iloc[10]
# IndexError

7.通过多个位置选择

为了按位置提取多行,我们将list或slice对象传递给.iloc[]索引器。

按位置选择多行

df.iloc[list_of_integers]
df.iloc[slice_of_integers]

下面的代码块演示如何使用整数列表选择数据帧的前五行。

# 使用列表选择dataframe的前5行
df_employees.iloc[[0, 1, 2, 3, 4]]v

Pandas的数据过滤实现

或者,我们可以使用切片表示法得到相同的结果。

# 使用切片选择dataframe的前5行
df_employees.iloc[0:5]

Pandas的数据过滤实现

如上所示,Python切片规则(半开区间)适用于.iloc[]属性,这意味着包含第一个索引,但不包括结束索引。

8.同时选择行和列

到目前为止,我们已经学习了如何使用.loc[]和.iloc[]索引器按标签或位置选择数据帧中的行。但是,这两个索引器不仅能够同时选择行,还可以同时选择行和列。

为此,我们必须提供用逗号分隔的行和列标签/位置,如下所示:

同时选择行和列

df.loc[row_labels, column_labels]
df.iloc[row_positions, column_positions]

其中行标签和列标签可以是单个字符串、字符串列表或字符串片段。同样,行位置和列位置可以是单个整数、整数列表或整数切片。

下面的示例演示如何使用.loc[]和.iloc[]索引器同时提取行和列。

选择标量值

我们选择id为478的员工的工资,方法如下。

# 按位置选择身份证号为478的员工的工资
df_employees.iloc[1, 3]

# 根据标签选择id号为478的员工的工资
df_employees.loc['478', 'salary']
# 54000

在本例中,两个索引器的输出都是整数。

选择单行和多列

我们选择id号为478的员工的姓名、姓氏和薪水,方法是将一个值作为第一个参数,将一个值列表作为第二个参数,从而获得一个Series对象。

# 按职位选择身份证号为478的员工的姓名、姓氏和工资
df_employees.iloc[1, [0, 1, 3]]

# 通过标签选择身份证号为478的员工的姓名、姓氏和工资
df_employees.loc['478', ['name', 'surname', 'salary']]

Pandas的数据过滤实现

选择不相交的行和列

要选择多行和多列,我们需要向两个索引器传递两个值列表。下面的代码显示如何提取id号为478和222的员工的姓名、姓氏和工资。

# 按职位选择身份证号为478和222的员工的姓名、姓氏和工资
df_employees.iloc[[1, 9], [0, 1, 3]]

# 根据标签选择身份证号为478和222的员工的姓名、姓氏和工资
df_employees.loc[['478', '222'], ['name', 'surname', 'salary']]

Pandas的数据过滤实现

与以前不同,这两个索引器的输出都是一个DataFrame对象。

选择连续的行和列

我们可以使用切片表示法提取数据帧的连续行和列。下面的代码片段显示如何选择id号为128、478、257和299的员工的姓名、姓氏和薪水。

# 按职位选择id号为128、478、257、299的员工的姓名、姓氏和工资
df_employees.iloc[:4, [0, 1, 3]]

# 按标签选择id号为128、478、257、299的员工的姓名、姓氏和工资
df_employees.loc[:'299', ['name', 'surname', 'salary']]

Pandas的数据过滤实现

如上所示,我们只使用切片表示法来提取数据帧的行,因为我们要选择的id号是连续的(索引从0到3)。

一定要记住.loc[]索引器使用一个闭合的间隔,同时提取开始标签和停止标签。相反,.iloc[]索引器使用半开区间,因此不包括停止索引处的值。

9.使用.at[]和.iat[]索引器选择标量值

如上所述,我们可以通过将两个用逗号分隔的字符串/整数传递给.loc[]和.iloc[]索引器来选择标量值。此外,Pandas还提供了两个优化函数来从数据帧对象中提取标量值:.at[]和.iat[]运算符。前者通过标签提取单个值,而后者通过位置访问单个值。

通过标签和位置选择标量值

df.at[string, string]
df.iat[integer, integer]

下面的代码显示如何使用.at[]和.iat[]索引器按标签和位置选择id号为478的员工的工资。

# 按位置选择身份证号为478的员工的工资
df_employees.iat[1, 3]

# 根据标签选择id号为478的员工的工资
df_employees.at['478', 'salary']
# 54000

我们可以使用%timeit magic函数来计算这两个Python语句的执行时间。如下所示,.at[]和.iat[]运算符比.loc[]和.iloc[]索引器快得多。

# loc索引器的执行时间
%timeit df_employees.loc['478', 'salary']

# at索引器的执行时间
%timeit df_employees.at['478', 'salary']

Pandas的数据过滤实现

# iloc索引器的执行时间
%timeit df_employees.iloc[1, 3]

# iat索引器的执行时间
%timeit df_employees.iat[1, 3]

Pandas的数据过滤实现

最后,必须记住,.at[]和.iat[]索引器只能用于访问单个值,在尝试选择数据帧的多个元素时会引发类型错误。

# 当尝试选择多个元素时,会引发异常
df_employees.at['478', ['name', 'surname', 'salary']]
# TypeError

10.使用布尔选择行

到目前为止,我们已经根据标签和位置过滤了数据帧中的行和列。或者,我们也可以用布尔索引在Pandas中选择一个子集。布尔选择包括通过为每一行提供布尔值(True或False)来选择数据帧的行。

在大多数情况下,这个布尔数组是通过将一个条件应用于一个或多个列的值来计算的,该条件的计算结果为True或False,具体取决于这些值是否满足条件。但是,也可以使用其他序列、Numpy数组、列表或Pandas系列手动创建布尔数组。

然后,布尔值序列放在方括号[]内,返回与真值相关联的行。

使用布尔选择选择选择行

df[sequence_of_booleans]

根据单列值的布尔选择

根据单列值过滤数据帧的最常见方法是使用比较运算符。

比较运算符计算两个操作数(A和b)之间的关系,并根据是否满足条件返回True或False。下表包含Python中可用的比较运算符。

Pandas的数据过滤实现

这些比较运算符可用于数据帧的单列,以获得布尔值序列。例如,我们使用大于运算符确定员工的工资是否大于45000,如下所示。

# 工资超过45000的员工
df_employees['salary'] > 45000
1

Pandas的数据过滤实现

输出是一系列布尔函数,其中工资高于45000为真,低于或等于45000为假。正如你可能注意到的那样,boolean系列具有与原始数据帧相同的索引(id编号)。

可以将此序列传递给索引运算符[],以仅返回结果为True的行。

# 选择工资高于45000的员工
df_employees[df_employees['salary'] > 45000]

Pandas的数据过滤实现

如上所示,我们获得了一个数据帧对象,其中只包含工资高于45000的员工。

根据多列值的布尔选择

之前,我们已经根据一个条件过滤了一个数据帧。但是,我们也可以使用逻辑运算符将多个布尔表达式组合在一起。

在Python中,有三个逻辑运算符:and、or和not。但是,这些关键字在Pandas中不可用于组合多个布尔条件。而是使用以下运算符。

Pandas的数据过滤实现

下面的代码展示了如何选择薪水高于45000的员工,以及有一份永久合同,其中包含两个布尔表达式和逻辑运算符&。

# 选择工资高于45000并有长期合同的员工
df_employees[(df_employees['salary'] > 45000) & (df_employees['type_contract'] == 'permanent')]

Pandas的数据过滤实现

如你所知,在Python中,比较运算符的优先级高于逻辑运算符。但是,它不适用于逻辑运算符优先于比较运算符的panda。因此,我们需要将每个布尔表达式包装在括号中以避免错误。

使用Pandas方法的布尔选择

Pandas提供了一系列返回布尔值序列的内置函数,它是结合比较运算符和逻辑运算符的更复杂布尔表达式的一个有吸引力的替代方案。

isin方法

这个pandas.Series.isin方法接受一系列值,并在序列中与列表中的值匹配的位置返回True。

此方法允许我们检查列中是否存在一个或多个元素,而无需使用逻辑运算符或。下面的代码显示如何使用逻辑运算符or和isin方法选择具有永久或临时合同的员工。

# 使用逻辑操作符或选择具有永久或临时合同的员工
df_employees[(df_employees['type_contract'] == 'temporary') | (df_employees['type_contract'] == 'permanent')]

# 使用isin方法选择有永久或临时合同的员工
df_employees[df_employees['type_contract'].isin(['temporary', 'permanent'])]

Pandas的数据过滤实现

如你所见,isin方法在检查同一列中的多个或条件时非常方便。另外,它更快!

# 使用逻辑运算符|执行时间
%timeit df_employees[(df_employees['type_contract'] == 'temporary') | (df_employees['type_contract'] == 'permanent')]

# isin方法的执行时间
%timeit df_employees[df_employees['type_contract'].isin(['temporary', 'permanent'])]

Pandas的数据过滤实现

between方法

这个熊猫系列方法接受两个用逗号分隔的标量,它们表示一个值范围的上下边界,并在该范围内的位置返回True。

以下代码选择工资高于或等于30000且小于或等于80000的员工。

# 薪资高于或等于30000,低于或等于80000的员工
df_employees[df_employees['salary'].between(30000, 80000)]

Pandas的数据过滤实现

如你所见,这两个边界(30000和80000)都包括在内。要排除它们,我们必须按以下方式传递inclusive=False参数。

# 薪资在3万以上,8万以下的员工
df_employees[df_employees['salary'].between(30000, 80000, inclusive=False)]

Pandas的数据过滤实现

正如你可能注意到的,上面的代码相当于编写两个布尔表达式,并使用逻辑运算符and对它们求值。

# 薪资高于或等于30000,低于或等于80000的员工
df_employees[(df_employees['salary']>=30000) & (df_employees['salary']<=80000)]

字符串方法

此外,我们还可以将布尔索引与字符串方法一起使用,只要它们返回布尔值序列。

例如pandas.Series.str.contains方法检查列的所有元素中是否存在子字符串,并返回一系列布尔值,我们可以将这些布尔值传递给索引运算符以筛选数据帧。

下面的代码显示如何选择包含57的所有电话号码。

# 选择所有包含57的电话号码
df_employees[df_employees['telephone'].str.contains('57')]

Pandas的数据过滤实现

当contains方法计算子字符串是否包含在序列的每个元素中。pandas.Series.str.startswith函数检查字符串开头是否存在子字符串。同样地pandas.Series.str.endswith测试字符串末尾是否存在子字符串。

以下代码显示如何选择姓名以“A”开头的员工。

# 选择名字以“A”开头的员工
df_employees[df_employees['name'].str.startswith('A')]

Pandas的数据过滤实现

摘要

在本文中,我们学习从Dataframe中选择子集。此外,我们还提供了多个使用示例。现在!现在是时候在清理你自己的数据时应用这些技术了!

到此这篇关于Pandas的数据过滤实现的文章就介绍到这了,更多相关Pandas 数据过滤内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python解决鸡兔同笼问题的方法
Dec 20 Python
pygame加载中文名mp3文件出现error
Mar 31 Python
python和ruby,我选谁?
Sep 13 Python
Python实现学生成绩管理系统
Apr 05 Python
Python获取指定文件夹下的文件名的方法
Feb 06 Python
python在TXT文件中按照某一字符串取出该字符串所在的行方法
Dec 10 Python
Pytorch的mean和std调查实例
Jan 02 Python
使用Django实现把两个模型类的数据聚合在一起
Mar 28 Python
利用python实现凯撒密码加解密功能
Mar 31 Python
利用Pycharm + Django搭建一个简单Python Web项目的步骤
Oct 22 Python
Python获取指定网段正在使用的IP
Dec 14 Python
Python面向对象编程之类的概念
Nov 01 Python
Python爬虫定时计划任务的几种常见方法(推荐)
Jan 15 #Python
python 如何把docker-compose.yaml导入到数据库相关条目里
Jan 15 #Python
pandas针对excel处理的实现
Jan 15 #Python
详解Python中的文件操作
Jan 14 #Python
python中的时区问题
Jan 14 #Python
Python截图并保存的具体实例
Jan 14 #Python
Python从MySQL数据库中面抽取试题,生成试卷
Jan 14 #Python
You might like
PHP把网页保存为word文件的三种方法
2014/04/01 PHP
Javascript客户端将指定区域导出到Word、Excel的代码
2008/10/22 Javascript
JavaScript中使用typeof运算符需要注意的几个坑
2014/11/08 Javascript
javascript的push使用指南
2014/12/05 Javascript
jquery搜索框效果实现方法
2015/01/16 Javascript
JavaScript计算两个日期时间段内日期的方法
2015/03/16 Javascript
JS实现动态给图片添加边框的方法
2015/04/01 Javascript
.NET微信公众号开发之创建自定义菜单
2015/07/16 Javascript
AngularJS入门教程之Select(选择框)详解
2016/07/27 Javascript
JS 判断某变量是否为某数组中的一个值的3种方法(总结)
2017/07/10 Javascript
20行JS代码实现粘贴板复制功能
2018/02/06 Javascript
webpack-dev-server自动更新页面方法
2018/02/22 Javascript
vue动态绑定组件子父组件多表单验证功能的实现代码
2018/05/14 Javascript
vue二级菜单导航点击选中事件的方法
2018/09/12 Javascript
js实现的订阅发布者模式简单示例
2020/03/14 Javascript
js实现点赞效果
2020/03/16 Javascript
JavaScript原生数组函数实例汇总
2020/10/14 Javascript
[02:32]DOTA2英雄基础教程 祸乱之源
2013/12/23 DOTA
python 多进程通信模块的简单实现
2014/02/20 Python
Python基于pygame实现的font游戏字体(附源码)
2015/11/11 Python
微信跳一跳小游戏python脚本
2018/01/05 Python
Python实现简单文本字符串处理的方法
2018/01/22 Python
Python实现的基于优先等级分配糖果问题算法示例
2018/04/25 Python
使用Python快速搭建HTTP服务和文件共享服务的实例讲解
2018/06/04 Python
python使用__slots__让你的代码更加节省内存
2018/09/05 Python
用Python画一个LinkinPark的logo代码实例
2019/09/10 Python
在python中logger setlevel没有生效的解决
2020/02/21 Python
Python任务自动化工具tox使用教程
2020/03/17 Python
德国化妆品和天然化妆品网上商店:kosmetikfuchs.de
2017/06/09 全球购物
会计专业自我鉴定范文
2013/12/29 职场文书
幼儿园运动会入场词
2014/02/10 职场文书
军训自我鉴定100字
2014/02/13 职场文书
护林防火标语
2014/06/27 职场文书
2014年督导工作总结
2014/11/19 职场文书
Python之matplotlib绘制折线图
2022/04/13 Python