在本文中,我们将介绍在 Python 中过滤 pandas 数据框的各种方法。数据过滤是最常见的数据操作之一。它类似于 SQL 中的 WHERE 子句,或者您必须在 MS Excel 中使用过滤器来根据某些条件选择特定的行。在速度方面,python 有一种高效的方式来执行过滤和聚合。它有一个名为 pandas 的优秀包,用于数据整理任务。Pandas 建立在用 C 语言编写的 numpy 包之上,这是一种低级语言。因此,使用 包进行数据操作是处理大型数据集的快速而智能的方法。
它是预测建模或任何报告项目的数据准备的最初始步骤之一。它也被称为“子集数据”。请参阅下面的一些数据过滤示例。
在提交以下代码之前, 请确保已安装pandas包,您可以通过在 Ipython 控制台中运行!pip show pandas
语句来检查它。如果没有安装,可以使用命令安装!pip install pandas
。
我们将使用包含 2013 年从纽约起飞的航班详细信息的数据集。该数据集有 336776 行和 16 列。请参阅下面的列名称。要导入数据集,我们使用read_csv( )
pandas 包中的函数。
['year', 'month', 'day', 'dep_time', 'dep_delay', 'arr_time', 'arr_delay', 'carrier', 'tailnum', 'flight', 'origin', 'dest', 'air_time', 'distance', 'hour', 'minute']
import pandas as pd df = pd.read_csv("https://raw.githubusercontent.com/JackyP/testing/master/datasets/nycflights.csv", usecols=range(1,17))
按列值过滤熊猫数据框
B6
,来自JFK
机场
newdf = df[(df.origin == "JFK") & (df.carrier == "B6")]
newdf.head() Out[23]: year month day dep_time ... air_time distance hour minute 3 2013 1 1 544.0 ... 183.0 1576 5.0 44.0 8 2013 1 1 557.0 ... 140.0 944 5.0 57.0 10 2013 1 1 558.0 ... 149.0 1028 5.0 58.0 11 2013 1 1 558.0 ... 158.0 1005 5.0 58.0 15 2013 1 1 559.0 ... 44.0 187 5.0 59.0 [5 rows x 16 columns]
- 过滤后的数据(子集化后)存储在名为
newdf
. - 符号
&
指的是AND
条件,这意味着同时满足这两个标准。 - 这部分代码
(df.origin == "JFK") & (df.carrier == "B6")
返回 True / False。条件匹配时为真,条件不成立时为假。稍后它在 df 中传递并返回与True对应的所有行。它返回 4166 行。
在 pandas 包中,有多种方法可以执行过滤。上面的代码也可以写成如下所示的代码。这种方法优雅且更具可读性,并且在指定列(变量)时无需每次都提及数据框名称。
newdf = df.query('origin == "JFK" & carrier == "B6"')
loc 是位置术语 的缩写。所有这 3 种方法都返回相同的输出。这只是过滤行的不同方式。
newdf = df.loc[(df.origin == "JFK") & (df.carrier == "B6")]
按行和列位置过滤 Pandas Dataframe
假设您要按位置选择特定行(比方说从第二行到第五行)。我们可以使用df.iloc[ ]
相同的功能。
Indexing in python starts from zero. df.iloc[0:5,] refers to first to fifth row (excluding end point 6th row here). df.iloc[0:5,] is equivalent to df.iloc[:5,]
df.iloc[:5,] #First 5 rows df.iloc[1:5,] #Second to Fifth row df.iloc[5,0] #Sixth row and 1st column df.iloc[1:5,0] #Second to Fifth row, first column df.iloc[1:5,:5] #Second to Fifth row, first 5 columns df.iloc[2:7,1:3] #Third to Seventh row, 2nd and 3rd column
loc根据索引标签考虑行。而iloc根据索引中的位置考虑行,因此它只需要整数。让我们创建一个示例数据以供说明
import numpy as np x = pd.DataFrame({"col1" : np.arange(1,20,2)}, index=[9,8,7,6,0, 1, 2, 3, 4, 5])
col1
9 1
8 3
7 5
6 7
0 9
1 11
2 13
3 15
4 17
5 19
根据索引或行位置选择行x.iloc[0:5] Output col1 9 1 8 3 7 5 6 7 0 9
根据索引标签选择行x.loc[0:5] Output col1 0 9 1 11 2 13 3 15 4 17 5 19
x.loc[0:5]
返回 6 行(包括第 6 个元素的 5 行)?
这是因为loc
不根据索引位置产生输出。它只考虑索引的标签,也可以是字母表,包括起点和终点。参考下面的例子。
x = pd.DataFrame({"col1" : range(1,5)}, index=['a','b','c','d']) x.loc['a':'c'] # equivalent to x.iloc[0:3] col1 a 1 b 2 c 3
按行位置和列名称过滤熊猫数据框
在这里,我们选择名为 origin 和 dest 的两列的前五行。
df.loc[df.index[0:5],["origin","dest"]]
df.index
返回索引标签。需要 df.index[0:5] 而不是 0:5(没有 df.index),因为索引标签并不总是按顺序从 0 开始。它可以从任何数字开始,甚至可以有字母。请参考我们展示 iloc 和 loc 比较的示例。
选择列的多个值
假设您想要包含始发地为 JFK 或 LGA 的所有航班详细信息。
# Long Way newdf = df.loc[(df.origin == "JFK") | (df.origin == "LGA")] # Smart Way newdf = df[df.origin.isin(["JFK", "LGA"])]
|
暗示 OR 条件,这意味着任何条件都成立。isin( )
类似于 SAS 和 R 中的 IN 运算符,它可以取很多值并应用 OR 条件。确保在列表 [ ] 中指定值。
选择列值不等于特定值的行
在此示例中,我们将删除起点来自 JFK 的所有航班详细信息。!=
暗示不等于。
newdf = df.loc[(df.origin != "JFK") & (df.carrier == "B6")]
让我们通过查看 newdf 中列 origin 的唯一值来检查上面的代码行是否正常工作。
pd.unique(newdf.origin)
['LGA', 'EWR']
如何否定整个条件
波浪号~
用于否定条件。它等同于 SAS 和 R 中的 NOT 运算符。
newdf = df[~((df.origin == "JFK") & (df.carrier == "B6"))]
在 Pandas Dataframe 中选择非缺失数据
通过使用notnull()
函数,您可以排除或删除 NA 和 NAN 值。在下面的示例中,我们从原始列中删除缺失值。由于此数据框不包含任何空白值,因此您会在 newdf 中找到相同数量的行。
newdf = df[df.origin.notnull()]
在 Pandas Dataframe 中过滤字符串
处理文本数据通常被认为是棘手的。但是 python 使处理字符或字符串列变得更容易。例如,让我们准备一个假数据。
import pandas as pd df = pd.DataFrame({"var1": ["AA_2", "B_1", "C_2", "A_2"]}) var1 0 AA_2 1 B_1 2 C_2 3 A_2
通过使用.str
,您可以启用字符串函数并可以应用于 pandas 数据框。str[0]表示第一个字母。
df[df['var1'].str[0] == 'A']
len( )
函数计算可迭代的长度。
df[df['var1'].str.len()>3]
contains( )
功能类似于 SQL 和 SAS 中的 LIKE 语句。您可以通过在 contains() 函数中提及模式来对数据进行子集化。
df[df['var1'].str.contains('A|B')] Output var1 0 AA_2 1 B_1 3 A_2
过滤时处理列名中的空格
让我们重命名列var1 ,在var 1之间留一个空格我们可以使用重命名函数重命名它。
df.rename(columns={'var1':'var 1'}, inplace = True)
通过使用反引号,` `
我们可以包含有空格的列。请参阅下面的示例代码。
newdf = df.query("`var 1` == 'AA_2'")
!pip show pandas
如果您的版本早于 0.25 版,则可以使用此命令升级它!pip install --upgrade pandas --user
如何在不使用 pandas 包的情况下过滤数据
您可以使用纯 python 方法执行过滤,而不依赖于 pandas 包。
我们不需要创建数据框来存储数据。我们可以将其存储在列表数据结构中。lst_df
包含从 CSV 文件导入的航班数据。
import csv import requests response = requests.get('https://dyurovsky.github.io/psyc201/data/lab2/nycflights.csv').text lines = response.splitlines() d = csv.DictReader(lines) lst_df = list(d)
Lambda 是定义用户定义函数的另一种方式。通过使用 lambda,您可以在一行代码中定义函数。
l1 = list(filter(lambda x: x["origin"] == 'JFK' and x["carrier"] == 'B6', lst_df))
如果你想知道如何在数据帧上使用这个 lambda 函数,你可以提交下面的代码。
newdf = df[df.apply(lambda x: x["origin"] == 'JFK' and x["carrier"] == 'B6', axis=1)]
列表推导式是 lambda 函数的替代方法,使代码更具可读性。
l2 = list(x for x in lst_df if x["origin"] == 'JFK' and x["carrier"] == 'B6')
您可以像下面所示的方式在数据框上使用列表理解。
newdf = df.iloc[[index for index,row in df.iterrows() if row['origin'] == 'JFK' and row['carrier'] == 'B6']]
Python 是一种面向对象的编程语言,其中的代码是使用class
.
class filter: def __init__(self, l, query): self.output = [] for data in l: if eval(query): self.output.append(data) l3 = filter(lst_df, 'data["origin"] == "JFK" and data["carrier"] == "B6"').output