Pandas where() 方法:带条件过滤

2023-10-12

The where中的方法Pandas允许您根据条件过滤 DataFrame 或 Series,类似于 SQL 的 WHERE 子句。

您是否曾经发现自己需要根据特定条件替换 DataFrame 中的某些值,或者可能想要屏蔽不符合某些条件的数据?

The where方法用于执行此类转换任务。

 

 

Pandas where语法和参数

The where方法语法如下所示:


DataFrame.where(cond, other=nan, inplace=False, axis=None, level=None)
  

我们来分解一下这些参数:

  • cond:这是一个条件,当满足时,保留原始值。如果不满足,则该值将被替换为中指定的值other范围。
  • other:条件为假时要替换的值。默认情况下,它是 NaN。
  • inplace:是直接修改调用对象还是返回一个新的对象。默认值为 False。
  • axis:用于对齐目的的可选参数。可以是索引 (0) 或列 (1)。
  • level:对于具有多级索引的DataFrame,应应用操作的级别。

 

使用过滤数据框where method

让我们根据标量条件执行基本过滤where method:


import pandas as pd
data = {'Scores': [85, 90, 78, 88, 76, 95, 89]}
df = pd.DataFrame(data)
high_scores = df.where(df['Scores'] > 80)
print(high_scores)
  

Output:


   Scores
0    85.0
1    90.0
2     NaN
3    88.0
4     NaN
5    95.0
6    89.0
  

从输出中,您可以看到小于或等于 80 的分数被 NaN 替换。

在接下来的部分中,我们将学习如何处理这些 NaN 值。

仅保留 80 分以上的分数high_scores数据框。

 

返回类型where Method

When where方法应用于DataFrame,它返回一个DataFrame;当用于系列时,它返回一个系列。

让我们通过一些例子来探讨这个概念:

使用数据框


import pandas as pd
data = {
    'Age': [25, 30, 35, 40],
    'Salary': [50000, 60000, 70000, 80000]
}
df = pd.DataFrame(data)
young_employees = df.where(df['Age'] < 35)
print(young_employees)
  

Output:


    Age   Salary
0  25.0  50000.0
1  30.0  60000.0
2   NaN      NaN
3   NaN      NaN
  

请注意,如果不满足条件,即使只指定了一列的条件,整行也会被屏蔽(用 NaN 替换)。

使用系列

如果我们应用where方法到 DataFrame 的单列(系列):


young_ages = df['Age'].where(df['Age'] < 35)
print(young_ages)
  

Output:


0    25.0
1    30.0
2     NaN
3     NaN
Name: Age, dtype: float64
  

这里,输出是一个 Series,而不是 DataFrame,因为我们将该方法应用于单个列。

 

创建带有条件的布尔掩码

的基础where方法的功能在于根据指定条件创建布尔掩码。

这些掩码本质上是数组或一系列True and False值,表示每个元素是否满足给定的条件。

给定一个数据框:


import pandas as pd
data = {
    'Name': ['Alice', 'Bob', 'Charlie', 'David'],
    'Age': [25, 28, 30, 23]
}
df = pd.DataFrame(data)
  

要为 28 岁以下创建布尔掩码:


age_mask = df['Age'] < 28
print(age_mask)
  

Output:


0     True
1    False
2    False
3     True
Name: Age, dtype: bool
  

该掩码表示第一个和最后一个条目满足条件。

使用布尔蒙版应用where

然后面膜就可以直接使用了where method:


younger_ages = df['Age'].where(age_mask)
print(younger_ages)
  

Output:


0    25.0
1     NaN
2     NaN
3    23.0
Name: Age, dtype: float64
  

 

使用等于和不等于

比较运算符允许我们创建条件来根据需要过滤数据。

让我们看看这些运算符在 Pandas 领域如何运作。

对于示例数据帧:


import pandas as pd
data = {
    'Grade': [85, 90, 78, 88, 76, 95, 89]
}
df = pd.DataFrame(data)
  

Using ==(平等):

仅过滤恰好为 88 的成绩:


exact_grade = df['Grade'].where(df['Grade'] == 88)
print(exact_grade)
  

Output:


0    NaN
1    NaN
2    NaN
3    88.0
4    NaN
5    NaN
6    NaN
Name: Grade, dtype: float64
  

不平等与不平等

The !=当您想要排除特定值时,(不等于)运算符至关重要:


# All grades that are not 88
not_eighty_eight = df['Grade'].where(df['Grade'] != 88)
print(not_eighty_eight)
  

Output:


0    85.0
1    90.0
2    78.0
3     NaN
4    76.0
5    95.0
6    89.0
Name: Grade, dtype: float64
  

 

组合多个条件

通过使用链接多个条件&, |, and ~运算符,您可以在 Pandas 中定义更复杂的数据过滤器。

为此,让我们继续我们的成绩示例:


import pandas as pd
data = {
    'Grade': [85, 90, 78, 88, 76, 95, 89],
    'Status': ['Pass', 'Pass', 'Fail', 'Pass', 'Fail', 'Pass', 'Pass']
}
df = pd.DataFrame(data)
  

使用 & (AND) 运算符

要过滤大于 80 且状态为“通过”的成绩:


high_passing_grades = df.where((df['Grade'] > 80) & (df['Status'] == 'Pass'))
print(high_passing_grades)
  

Output:


   Grade Status
0   85.0   Pass
1   90.0   Pass
2    NaN    NaN
3   88.0   Pass
4    NaN    NaN
5   95.0   Pass
6   89.0   Pass
  

使用 | (或)运算符

要过滤大于 90 或状态为“失败”的成绩:


high_or_fail = df.where((df['Grade'] > 90) | (df['Status'] == 'Fail'))
print(high_or_fail)
  

Output:


   Grade Status
0    NaN    NaN
1    NaN    NaN
2   78.0   Fail
3    NaN    NaN
4   76.0   Fail
5   95.0   Pass
6    NaN    NaN
  

使用 ~(非)运算符

要过滤不大于 90 的等级:


not_high_grades = df.where(~(df['Grade'] > 90))
print(not_high_grades)
  

Output:


   Grade Status
0   85.0   Pass
1   90.0   Pass
2   78.0   Fail
3   88.0   Pass
4   76.0   Fail
5    NaN    NaN
6   89.0   Pass
  

请记住,组合条件时,将每个条件括在括号中至关重要。

 

使用函数作为条件

的一个强大功能where方法是使用可调用对象(如函数)作为过滤条件的能力。

以下是如何在where method:

我们以下面的 DataFrame 为例:


import pandas as pd
data = {
    'Grade': [85, 90, 78, 88, 76, 95, 89]
}
df = pd.DataFrame(data)
  

假设我们要保留奇数的成绩:


def is_odd(num):
    return num % 2 == 1
odd_grades = df['Grade'].where(is_odd)
print(odd_grades)
  

Output:


0    85.0
1     NaN
2     NaN
3     NaN
4     NaN
5    95.0
6    89.0
Name: Grade, dtype: float64
  

 

就地修改

默认情况下,where方法不会改变原始的 DataFrame 或 Series。相反,它返回一个经过修改的新对象:

通过设置inplace参数为True,原始对象被修改:


df.where(df['Grade'] > 85, inplace=True)
  

Now, df直接反映了变化,保留了85以上的成绩,其他的则用NaN代替。没有返回新对象;所有修改均在df.

Note: 当使用大量 DataFrame 时,就地修改可以提高内存效率,因为它不会创建新对象。

 

处理 NaN 值

正如我们在前面的示例中看到的,不满足指定条件的条目将被替换为NaN values.

假设您希望将不满足条件的条目替换为静态值,例如 -1 而不是 NaN。


import pandas as pd
data = {
    'Grade': [85, 90, 78, 88, 76, 95, 89]
}
df = pd.DataFrame(data)
graded_df = df['Grade'].where(df['Grade'] > 85, other=-1)
  

Output:


0    -1
1    90
2    -1
3    88
4    -1
5    95
6    89
Name: Grade, dtype: int64
  

对不同的条目使用不同的值

如果您希望用不同的值替换每个不合格条目怎么办?这other参数可以处理数组或系列:


replacement_values = [10, 20, 30, 40, 50, 60, 70]
graded_df = df['Grade'].where(df['Grade'] > 85, other=replacement_values)
  

Output:


0    10
1    90
2    30
3    88
4    50
5    95
6    89
Name: Grade, dtype: int64
  

使用函数进行动态替换

对于更复杂的替换逻辑,还可以使用函数:


def custom_replacement(grade):
    return grade / 2
graded_df = df['Grade'].where(df['Grade'] > 85, other=custom_replacement)
  

Output:


0    42.5
1    90.0
2    39.0
3    88.0
4    38.0
5    95.0
6    89.0
Name: Grade, dtype: float64
  

The other中的参数where方法提供了额外的定制层。

 

where 与查询或布尔索引的性能

过滤数据时,会出现三种流行的选择:where方法,将查询方式,以及直接布尔索引。

让我们来衡量这些方法的性能。

首先,我们需要创建一个示例 DataFrame:


import pandas as pd
import numpy as np
np.random.seed(42)
df = pd.DataFrame({
    'A': np.random.randint(1, 1000, 1000000),
    'B': np.random.randint(1, 1000, 1000000)
})
  

对 where 方法进行计时


def using_where(df):
    return df.where(df['A'] > 50)
  

定时布尔索引


def using_boolean_indexing(df):
    return df[df['A'] > 50]
  

计时查询方法


def using_query(df):
    return df.query('A > 50')
  

现在,让我们使用 timeit 对这些函数进行计时:


import timeit
n_repeat = 3
n_iter = 10

where_time = timeit.timeit('using_where(df)', globals=globals(), number=n_iter) / n_iter
bool_idx_time = timeit.timeit('using_boolean_indexing(df)', globals=globals(), number=n_iter) / n_iter
query_time = timeit.timeit('using_query(df)', globals=globals(), number=n_iter) / n_iter

print(f"Average time using 'where' method over {n_iter} iterations: {where_time:.6f} seconds")
print(f"Average time using boolean indexing over {n_iter} iterations: {bool_idx_time:.6f} seconds")
print(f"Average time using 'query' method over {n_iter} iterations: {query_time:.6f} seconds")
  

Output:


Average time using 'where' method over 10 iterations: 0.061809 seconds
Average time using boolean indexing over 10 iterations: 0.025589 seconds
Average time using 'query' method over 10 iterations: 0.029168 seconds  

从上面的结果来看,布尔索引绝对是更快的方法。

 

Nested where Calls

如果您想顺序应用多个条件。实现此目的的一种方法是通过链接或嵌套where calls.

考虑一个简单的数据集:


import pandas as pd
data = {
    'Grade': [85, 90, 78, 88, 76, 95, 89],
    'Subject': ['Math', 'English', 'History', 'Math', 'English', 'History', 'Math']
}
df = pd.DataFrame(data)
  

想象一下,您想要过滤成绩高于 85 且主题为“数学”的条目的数据。

你可以连锁where calls:


filtered_df = df.where(df['Grade'] > 85).where(df['Subject'] == 'Math')
print(filtered_df)
  

Output:


   Grade Subject
0    NaN     NaN
1    NaN     NaN
2    NaN     NaN
3   88.0    Math
4    NaN     NaN
5    NaN     NaN
6   89.0    Math  

Nested whereother范围

您可以结合other复杂替换的参数:


replaced_df = df['Grade'].where(df['Grade'] > 85, other=-1).where(df['Subject'] == 'Math', other=-2)
print(replaced_df)
  

Output:


0    -1
1    -2
2    -2
3    88
4    -2
5    -2
6    89
Name: Grade, dtype: int64  

此处,低于 85 的成绩将替换为 -1,任何不是“数学”的行将进一步替换为 -2。

 

Resource

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.where.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Pandas where() 方法:带条件过滤 的相关文章

随机推荐

  • 纯Python直方图

    当您准备绘制直方图时 最简单的方法是不要考虑箱 而是报告每个值出现的次数 频率表 一条蟒蛇字典非常适合这项任务 gt gt gt gt gt gt Need not be sorted necessarily gt gt gt a 0 1
  • 了解日期和时间是混乱的

    日期和时间并不是简单的事情 尤其是现在大多数计算都是远程完成的 无法保证计算机和用户位于同一个地方 由于管理夏令时和时区的规则不是静态的 这一事实使情况变得更加复杂 在本课程中 您将探索所有奇怪的边缘情况 并了解程序员通常如何处理它们
  • 掌握Python的内置时间模块

    蟒蛇time模块提供了多种方式代表时间代码中 例如对象 数字和字符串 它还提供除表示时间之外的功能 例如在代码执行期间等待和测量代码的效率 本课程将引导您了解最常用的函数和对象time 完成本课程后 您将能够 理解处理日期和时间的核心概念
  • 关于奥尔德伦·桑托斯

    关于奥尔德伦 桑托斯 个人网站 大家好 我是 Aldren Santos 担任自由平面设计师 插画师已有 3 年了 我的任务是尽我所能 让这个网站变得更加精彩 我真心希望我的插图能够吸引您通过我们团队辛勤工作的这些教程学习 Python 的
  • 编写和测试 Python 函数:面试练习(概述)

    无论您是想在编码面试中取得好成绩 还是只是想提高您的开发技能 解决编码挑战可以帮助您成长为一名程序员 在这个真实的 Python 代码对话中 Philipp 向 Martin 提出挑战 要求他编写一个函数 将字符串中的每个字符加倍 通过他们
  • 引导 Django 项目

    有关本课程所涵盖概念的更多信息 您可以查看 如何设置 Django 项目 真正的Python文章 使用 Django 和 Python 构建个人日记 真正的Python文章 以下是本课程中使用的命令行片段 mkdir portfolio p
  • Python 石头剪刀布:命令行游戏(概述)

    游戏编程是学习如何编程的好方法 您可以使用许多在现实世界中看到的工具 此外您还可以玩游戏来测试您的结果 开始 Python 游戏编程之旅的理想游戏是剪刀石头布 在本课程中 您将学习如何 自己编写代码剪刀石头布游戏 接受用户输入input 使
  • 2021 年 4 月 21 日

    主持人大卫 阿莫斯回答会员的问题 在这次会议上 我们讨论了 Real Python 的新功能 在哪里可以找到要阅读的代码以提高您的 Python 技能 为什么 0xfor x in 1 2 3 回报 15 数据科学 Django 和 Fla
  • Python 中的 K 均值聚类:实用指南

    目录 What Is Clustering 聚类技术概述 分区聚类 层次聚类 基于密度的聚类 How to Perform K Means Clustering in Python 了解 K 均值算法 使用 Python 编写您的第一个 K
  • 在 Python 中使用 lru_cache 进行缓存

    有很多方法可以实现快速响应的应用程序 缓存是一种方法 如果使用得当 可以使事情变得更快 同时减少计算资源的负载 蟒蛇的功能工具模块附带 lru cache 装饰器 这使您能够使用以下命令缓存函数的结果最近最少使用 LRU 策略 这是一种简单
  • 拼写错误、缺失或误用 Python 关键字

    以下是有关 Python 关键字的更多信息的资源 Python 关键字 简介 真正的 Python 文章 Python 3 8 关键字 Python 文档
  • Python 标准 REPL:快速尝试代码和想法

    目录 Getting to Know the Python Standard REPL 什么是 Python 的交互式 Shell 或 REPL 为什么使用 Python REPL Starting and Ending REPL Inte
  • 使用 Fabric 和 Ansible 自动化 Django 部署

    目录 设置和配置 Fabric Setup 设置 SSH 密钥 强化用户密码 安装 Ansible 依赖项 将 SELinux 设置为宽容模式 升级服务器 完整性检查 Ansible Primer 剧本 示例手册 Playbook Setu
  • 第 27 集:准备面试 Python 练习题

    第 27 集 准备面试 Python 练习题 真正的 Python 播客 2020 年 9 月 18 日47m RSS Apple Podcasts Google Podcasts Spotify More 播客瘾君子 灰蒙蒙 袖珍铸件 投
  • Python 基础知识:函数和循环(摘要)

    在本视频课程中 您了解了两个最基本的概念 在编程中 函数和循环 首先 您学习了如何定义自己的自定义函数 你看到了 该函数由两部分组成 这函数签名 这开始于def关键字并包括函数名称和函数参数 这函数体 其中包含每当调用该函数时运行的代码 函
  • Python 的 urllib.request 用于 HTTP 请求

    目录 使用 urllib request 的基本 HTTP GET 请求 The Nuts and Bolts of HTTP Messages 了解什么是 HTTP 消息 了解 urllib request 如何表示 HTTP 消息 关闭
  • Django Ninja 的隐蔽 REST API(摘要)

    在本课程中 您已经了解了 Django Ninja REST API 库的所有内容 使用 Ninja 您可以 使用装饰器快速包装 Django 视图创建 REST API 端点 使用类型注释定义变量和参数 写Schema和ModelSche
  • Python 中的 Dijkstra 算法(查找最短路径)

    Dijkstra算法的工作原理是通过迭代找到节点的最短距离值 直到达到实际的最短距离 Dijkstra 算法的一个关键方面是它使用优先队列从尚未处理的节点集中选择具有最小暂定距离的顶点 当前节点被标记为已访问 并检查其所有邻居节点是否有更优
  • 使用 Pandas read_excel 读取 Excel 文件

    Pandas read excel是一个函数蟒蛇熊猫库允许我们在 Python 中读取 Excel 文件并将其转换为数据框 object read excel函数可以导入具有不同扩展名的Excel文件 例如 xls xlsx xlsm和 o
  • Pandas where() 方法:带条件过滤

    The where中的方法Pandas允许您根据条件过滤 DataFrame 或 Series 类似于 SQL 的 WHERE 子句 您是否曾经发现自己需要根据特定条件替换 DataFrame 中的某些值 或者可能想要屏蔽不符合某些条件的数