第二章:25+ Python 数据操作教程(第七节在Python 中过滤 pandas 数据框的10种方法)

本文介绍了在Python中使用pandas库进行数据过滤的各种方法,包括DataFrame条件过滤、查询函数以及loc和iloc函数的使用。通过示例展示了如何根据特定条件筛选数据,如选择特定航空公司和出发地的航班记录。此外,还提到了如何处理字符串数据和在不使用pandas时的过滤方法。
摘要由CSDN通过智能技术生成

在本文中,我们将介绍在 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))

按列值过滤熊猫数据框

选择 JetBlue Airways 的航班详情,该航班有 2 个字母的承运人代码B6,来自JFK机场

方法一:DataFrame方式
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]
  1. 过滤后的数据(子集化后)存储在名为newdf.
  2. 符号&指的是AND条件,这意味着同时满足这两个标准。
  3. 这部分代码(df.origin == "JFK") & (df.carrier == "B6")返回 True / False。条件匹配时为真,条件不成立时为假。稍后它在 df 中传递并返回与True对应的所有行。它返回 4166 行。
方法二:查询函数

在 pandas 包中,有多种方法可以执行过滤。上面的代码也可以写成如下所示的代码。这种方法优雅且更具可读性,并且在指定列(变量)时无需每次都提及数据框名称。

newdf = df.query('origin == "JFK" & carrier == "B6"')

如何在查询函数中传递变量

方法三:loc函数

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 函数的区别

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
iloc - 索引位置
x.iloc[0:5]

Output
   col1
9     1
8     3
7     5
6     7
0     9
根据索引或行位置选择行
loc - 索引标签
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
选择值以字母“A”开头的行

通过使用.str,您可以启用字符串函数并可以应用于 pandas 数据框。str[0]表示第一个字母。

df[df['var1'].str[0] == 'A']
过滤字符串长度大于 3 的行

len( )函数计算可迭代的长度。

df[df['var1'].str.len()>3]
选择包含字母 A 或 B 的字符串

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'")
pandas 包的0.25 版本支持反引号。在控制台中运行此命令以检查 pandas 版本!pip show pandas如果您的版本早于 0.25 版,则可以使用此命令升级它!pip install --upgrade pandas --user

如何在不使用 pandas 包的情况下过滤数据

您可以使用纯 python 方法执行过滤,而不依赖于 pandas 包。

警告:下面显示的过滤方法不是有效的方法。展示以下方法的主要目的是展示如何在不使用 pandas 包的情况下进行子集化。在您的实际项目中,您应该使用 pandas 的内置函数(query( )、loc[ ]、iloc[ ]),这些函数在上面已经解释过了。

我们不需要创建数据框来存储数据。我们可以将其存储在列表数据结构中。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 是定义用户定义函数的另一种方式。通过使用 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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值