作者|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']# 蕴含员工信息的dataframedf_employees = pd.DataFrame({'name': name, 'surname': surname, 'division': division,                             'salary': salary, 'telephone': telephone, 'type_contract': type_contract}, index=id_number)df_employees

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

如上所示,当检索单个列时,后果是一个Series对象。为了在只抉择一列时取得一个DataFrame对象,咱们须要传入一个列表,而不仅仅是一个字符串。

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

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


2.按标签抉择多列

咱们能够通过传入一个列名称如下的列表来抉择一个数据帧的多个列。

按标签抉择多列

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

如上所示,后果是一个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

如前所述,select_dtypes()办法能够同时承受字符串和numpy对象作为输出。下表显示了在Pandas中援用数据类型的最罕用办法。

作为揭示,咱们能够应用pandas.DataFrame.info办法或应用pandas.DataFrame.dtypes属性。前者打印数据帧的扼要摘要,包含列名及其数据类型,而后者返回一个蕴含每个列的数据类型的序列。

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

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

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']

如上所示,入选中一行时,.loc[]索引器将返回一个Series对象。然而,咱们也能够通过将单个元素列表传递给.loc[]办法来取得单行数据帧,如下所示。

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

5.按标签抉择多行

咱们能够应用.loc[]索引器抉择多行。除单个标签外,索引器还承受一个列表或标签片段作为输出。

按标签抉择多行

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

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

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

请留神,始终蕴含.loc[]办法的完结索引,这意味着所选内容包含最初一个标签。

6.按地位抉择单行

iloc[]索引器用于按地位索引数据帧。要应用.iloc[]属性抉择单行,咱们将行地位(单个整数)传递给索引器。

按地位抉择单行

df.iloc[integer]

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

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

此外,.iloc[]索引器还反对负整数(从-1开始)作为绝对于数据帧开端的绝对地位。

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

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

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

最初,请记住,在尝试拜访超出边界的索引时会引发索引器谬误。

# 数据框的形态- 10行6列df_employees.shape# (10, 6)# 当试图拜访一个越界的索引时,会引发一个IndexErrordf_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

或者,咱们能够应用切片表示法失去雷同的后果。

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

如上所示,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']]

  • 抉择不相交的行和列

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

# 按职位抉择身份证号为478和222的员工的姓名、姓氏和工资df_employees.iloc[[1, 9], [0, 1, 3]]# 依据标签抉择身份证号为478和222的员工的姓名、姓氏和工资df_employees.loc[['478', '222'], ['name', 'surname', 'salary']]

与以前不同,这两个索引器的输入都是一个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']]

如上所示,咱们只应用切片表示法来提取数据帧的行,因为咱们要抉择的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']

# iloc索引器的执行工夫%timeit df_employees.iloc[1, 3]# iat索引器的执行工夫%timeit df_employees.iat[1, 3]

最初,必须记住,.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中可用的比拟运算符。

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

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

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

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

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

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

依据多列值的布尔抉择

之前,咱们曾经依据一个条件过滤了一个数据帧。然而,咱们也能够应用逻辑运算符将多个布尔表达式组合在一起。

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

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

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

如你所知,在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'])]

如你所见,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'])]

between办法

这个熊猫系列办法承受两个用逗号分隔的标量,它们示意一个值范畴的高低边界,并在该范畴内的地位返回True。

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

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

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

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

正如你可能留神到的,下面的代码相当于编写两个布尔表达式,并应用逻辑运算符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')]

当contains办法计算子字符串是否蕴含在序列的每个元素中。pandas.Series.str.startswith函数查看字符串结尾是否存在子字符串。同样地pandas.Series.str.endswith测试字符串开端是否存在子字符串。

以下代码显示如何抉择姓名以“A”结尾的员工。

# 抉择名字以“A”结尾的员工df_employees[df_employees['name'].str.startswith('A')]

摘要

在本文中,咱们学习从Dataframe中抉择子集。此外,咱们还提供了多个应用示例。当初!当初是时候在清理你本人的数据时利用这些技术了!

原文链接:https://towardsdatascience.co...

欢送关注磐创AI博客站:
http://panchuang.net/

sklearn机器学习中文官网文档:
http://sklearn123.com/

欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/