Python
Pandas Where: 掌握强大的过滤工具

Pandas Where: 掌握强大的过滤工具

MoeNagy Dev

Pandas Where的基础知识

了解pandas where()方法的目的和功能

Pandas库中的where()方法是一个强大的条件过滤和数据选择工具。它允许您通过对现有的DataFrame或Series应用布尔条件来创建新的DataFrame或Series,同时保留原始数据的结构和形状。

where()方法的基本语法如下:

df.where(condition, other=None, inplace=False, axis=None, level=None, errors='raise', try_cast=False)

其中,condition是一个布尔表达式,用于确定哪些元素应该被保留。other参数指定不满足条件的元素应该使用的值。

认识条件过滤在数据分析中的重要性

条件过滤是数据分析中的一个基本操作,它允许您关注数据中与您的分析相关的特定子集。当处理大型或复杂的数据集时,这尤其有用,因为您需要快速识别和提取最重要的信息,以满足您的研究或业务目标。

通过掌握Pandas中的where()方法,您可以解锁强大的数据操作功能,实现以下目标:

  • 识别数据中的异常值或异常情况
  • 根据特定标准(如日期范围或地理位置)过滤数据
  • 对数据执行条件计算或转换
  • 结合多个条件来细化数据选择
  • 集成条件日志。 将 where() 方法整合到您的数据处理工作流中

理解并有效地使用 where() 方法是任何数据分析师或数据科学家在使用 Pandas 时的关键技能。

将 Pandas Where 应用于数值数据

基于数值条件过滤行

让我们从探索如何使用 where() 方法根据数值条件过滤 DataFrame 中的行开始。假设我们有一个 DataFrame df,其数据如下:

   age  income
0   25   50000
1   32   65000
2   41   75000
3   28   45000
4   35   60000

要只选择 age 大于 30 的行,我们可以使用以下代码:

df_older = df.where(df['age'] > 30)
df_older

这将给我们一个新的 DataFrame df_older,其数据如下:

     age  income
1   32.0  65000
2   41.0  75000
4   35.0  60000

请注意,条件 df['age'] > 30 不满足的行已被替换为 NaN 值。

使用逻辑运算符(and、or、not)组合多个条件

您还可以使用逻辑运算符如 andornot 组合多个条件。例如,要选择 age 在 30 到 40 之间(包括)的行,可以使用以下代码:

df_middle_age = df.where((df['age'] >= 30) & (df['age'] <= 40))
df_middle_age

这将给我们一个新的 DataFrame df_middle_age,其数据如下:

     age  income
1   32.0  65000
4   35.0  60000

使用 pandas where() 处理缺失值

where() 方法也可用于处理数据中的缺失值。如果您想用特定的值替换 NaN 值,可以使用 other 参数。例如,要将 NaN 值替换为 0,可以使用以下代码:

df_filled = df.where(df['age'] > 30, 0)
df_filled

这将给我们一个新的 DataFrame df_filled,其数据如下:

    age  income
0  25.0  50000
1  32.0  65000
2  41.0  75000
3   0.0  45000
4  35.0  6000.

Pandas 中的布尔掩码 where 操作

创建用于条件过滤的布尔掩码

除了直接在 where() 方法中使用布尔表达式,您还可以创建布尔掩码并使用它们来过滤数据。当您需要将相同的条件应用于多个列,或者想在代码的多个部分重复使用复杂的条件时,这种方法特别有用。

例如,让我们创建一个布尔掩码,选择 age 大于 30 且 income 大于 60,000 的行:

mask = (df['age'] > 30) & (df['income'] > 60000)
df_filtered = df.where(mask)
df_filtered

这将为我们提供一个新的 DataFrame df_filtered,其数据如下:

     age  income
1   32.0  65000
2   41.0  75000

利用布尔掩码进行高级数据选择

布尔掩码也可用于执行更复杂的数据选择操作。例如,您可以使用布尔掩码来选择特定的行和列,或者根据条件逻辑创建新的列。

假设我们想创建一个新的列 high_income,如果 income 大于 60,000,则为 True,否则为 False。我们可以使用 where() 方法和布尔掩码来实现:

df['high_income'] = df['income'].where(df['income'] > 60000, False)
df

这将为我们提供以下 DataFrame:

    age  income high_income
0   25  50000       False
1   32  65000        True
2   41  75000        True
3   28  45000       False
4   35  60000       False

使用布尔掩码优化性能

使用布尔掩码还可以帮助提高 Pandas 操作的性能,特别是在处理大型数据集时。布尔运算通常比逐行遍历 DataFrame 更快,所以利用布尔掩码可以使您的代码更加高效和可扩展。

Pandas 中基于文本和分类数据的 where 操作

基于字符串或分类条件过滤行

where(). Pandas 中的 where()` 方法不仅限于数字数据;您还可以使用它根据字符串或分类条件过滤行。当处理基于文本的数据或已编码为类别的数据时,这可能特别有用。

例如,假设我们有一个 DataFrame df,其中包含以下数据:

   name  department
0  Alice       Sales
1   Bob   Marketing
2  Carol  Accounting
3  David       Sales
4  Emily   Marketing

要选择 department 为 'Sales' 的行,我们可以使用以下代码:

# 选择 department 为 'Sales' 的行
df_sales = df.where(df['department'] == 'Sales')
df_sales

这将为我们创建一个新的 DataFrame df_sales,其中包含以下数据:

     name department
0  Alice     Sales
3  David     Sales

处理大小写敏感和部分匹配

默认情况下,where() 方法中的字符串比较是区分大小写的。如果需要执行不区分大小写的比较,可以使用 str.lower()str.upper() 方法来规范化文本,然后应用条件。

例如,要选择 name 包含子字符串 'a' 的行,而不考虑大小写,可以使用以下代码:

# 选择 name 包含 'a' 的行,不区分大小写
df_a_names = df.where(df['name'].str.contains('a', case=False))
df_a_names

这将为我们创建一个新的 DataFrame df_a_names,其中包含以下数据:

     name  department
0  Alice     Sales
2  Carol  Accounting
4  Emily   Marketing

将基于文本的条件与 pandas where() 结合使用

您还可以使用与用于数字条件相同的逻辑运算符(andornot)来组合多个基于文本的条件。这允许您根据数据的特性创建更复杂的过滤规则。

例如,要选择 department 为 'Sales' 或 'Marketing' 的行,可以使用以下代码:

# 选择 department 为 'Sales' 或 'Marketing' 的行
df_sales_or_marketing = df.where((df['department'] == 'Sales') | (df['department'] == 'Marketing'))
df_sales_or_marketing

这将为我们创建一个新的 DataFrame df_sales_or_marketing,其中包含以下数据:

     name  department
0  Alice     Sales
1   Bob   Marketing
3  David     Sales
4  Emily   Marketing

taFrame df_sales_or_marketing` 包含以下数据:

     name  department
0  Alice     Sales
1    Bob   Marketing
3  David     Sales
4  Emily   Marketing

Pandas 中的 where() 数据转换

使用 pandas where() 进行选择性数据更新

where() 方法也可用于选择性地更新 DataFrame 或 Series 中的值。当您需要应用条件逻辑来修改数据中的特定元素时,这可能很有用。

例如,假设我们想要将所有年龄大于 35 岁的员工的 income 值增加 10%。我们可以使用以下代码来实现:

df['income'] = df['income'].where(df['age'] <= 35, df['income'] * 1.1)
df

这将给我们以下更新后的 DataFrame:

    age  income
0   25  50000.0
1   32  65000.0
2   41  82500.0
3   28  45000.0
4   35  66000.0

将条件逻辑应用于修改特定列

where() 方法也可用于将条件逻辑应用于修改 DataFrame 中的特定列。这在数据清洗、特征工程或其他数据转换任务中可能很有用。

例如,假设我们想将所有负 income 值替换为 0。我们可以使用以下代码来实现:

df['income'] = df['income'].where(df['income'] >= 0, 0)
df

这将给我们以下更新后的 DataFrame:

    age  income
0   25  50000.0
1   32  65000.0
2   41  75000.0
3   28  45000.0
4   35  60000.0

将 pandas where() 集成到数据清洗和预处理工作流中

where() 方法可以是数据清洗和预处理任务的强大工具。通过将其与其他 Pandas 操作相结合,您可以创建复杂的数据转换工作流,能够处理各种数据相关的挑战。

例如,您可以使用 where() 来识别和处理异常值,填充缺失值,或根据特定条件对分类变量进行编码。通过将 where() 纳入您的数据预处理流程,您可以创建更加灵活和强大的数据转换管道。# Pandas Where 和 Groupby 操作

在 groupby 上下文中应用 pandas where()

where() 方法也可以与 Pandas 的 groupby() 功能结合使用, 在组级别上执行条件过滤和选择。

例如, 我们有一个 DataFrame df, 其数据如下:

   department  age  income
0      Sales   25  50000
1   Marketing   32  65000
2  Accounting   41  75000
3      Sales   28  45000
4   Marketing   35  60000

要选择每个部门中年龄大于部门平均年龄的员工, 我们可以使用以下代码:

dept_avg_age = df.groupby('department')['age'].transform('mean')
df_filtered = df.where(df['age'] > dept_avg_age)
df_filtered

这将给我们一个新的 DataFrame df_filtered, 其数据如下:

   department   age  income
1   Marketing  32.0  65000
2  Accounting  41.0  75000

条件聚合和组级别过滤

where() 方法也可用于在 groupby() 上下文中执行条件聚合或组级别过滤。这对于计算组特定指标或识别满足特定条件的子组很有用。

例如, 要计算每个部门中年龄大于 30 岁的员工的平均收入, 我们可以使用以下代码:

df.loc[df['age'] > 30].groupby('department')['income'].mean()

这将给我们以下输出:

department
Accounting    75000.0
Marketing     62500.0
Sales         55000.0
Name: income, dtype: float64

探索在基于组的分析中使用 pandas where() 的用例

where()groupby() 的组合为基于组的数据分析开辟了广泛的可能性。其他一些用例包括:

  • 识别表现出色或表现不佳的使用数据结构

列表

列表是 Python 中最通用的数据结构。它们可以包含不同数据类型的元素,并且它们的大小可以动态地改变。下面是一个创建和操作列表的示例:

# 创建一个列表
my_list = [1, 2, 3, 'four', 5.6]
 
# 访问元素
print(my_list[0])  # 输出: 1
print(my_list[-1])  # 输出: 5.6
 
# 修改元素
my_list[2] = 'three'
print(my_list)  # 输出: [1, 2, 'three', 'four', 5.6]
 
# 添加元素
my_list.append(6)
my_list.insert(2, 'new')
print(my_list)  # 输出: [1, 2, 'new', 'three', 'four', 5.6, 6]
 
# 删除元素
del my_list[3]
my_list.remove('four')
print(my_list)  # 输出: [1, 2, 'new', 5.6, 6]

元组

元组与列表类似,但它们是不可变的,这意味着它们的元素在创建后不能被修改。元组使用圆括号定义,而不是方括号。

# 创建一个元组
my_tuple = (1, 2, 'three', 4.5)
 
# 访问元素
print(my_tuple[0])  # 输出: 1
print(my_tuple[-1])  # 输出: 4.5
 
# 尝试修改元组会引发错误
# my_tuple[2] = 'new'  # TypeError: 'tuple' object does not support item assignment

字典

字典是无序的键值对集合。它们使用花括号 {} 定义,每个键值对由冒号 : 分隔。

# 创建一个字典
person = {
    'name': 'John Doe',
    'age': 35,
    'occupation': 'Software Engineer'
}
 
# 访问值
print(person['name'])  # 输出: John Doe
print(person.get('age'))  # 输出: 35
 
# 添加/修改元素
person['email'] = 'john.doe@example.com'
person['age'] = 36
print(person)  # 输出: {'name': 'John Doe', 'age': 36, 'occupation': 'Software Engineer', 'email': 'john.doe@example.com'}
 
# 删除元素
del person['occupation']
print(person)  # 输出: {'name': 'John Doe', 'age': 36, 'email': 'john.doe@example.com'}

集合

集合是无序的唯一元素的集合。

集合

集合是一种无序且唯一的元素集合。它们使用花括号 {}set() 函数定义。

# 创建集合
my_set = {1, 2, 3, 4, 5}
print(my_set)  # 输出: {1, 2, 3, 4, 5}
 
# 添加元素
my_set.add(6)
print(my_set)  # 输出: {1, 2, 3, 4, 5, 6}
 
# 删除元素
my_set.remove(3)
print(my_set)  # 输出: {1, 2, 4, 5, 6}
 
# 集合操作
set1 = {1, 2, 3}
set2 = {2, 3, 4}
print(set1 | set2)  # 并集: {1, 2, 3, 4}
print(set1 & set2)  # 交集: {2, 3}
print(set1 - set2)  # 差集: {1}

控制流

条件语句

Python 中的条件语句允许您根据特定条件执行不同的代码块。

# If-else 语句
age = 18
if age >= 18:
    print("您是成年人。")
else:
    print("您是未成年人。")
 
# Elif 语句
score = 85
if score >= 90:
    print("A")
elif score >= 80:
    print("B")
elif score >= 70:
    print("C")
else:
    print("D")

循环

Python 中的循环允许您重复执行一个代码块。

# For 循环
fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
    print(fruit)
 
# While 循环
counter = 0
while counter < 5:
    print(counter)
    counter += 1

列表推导式

列表推导式提供了一种简洁的方式在 Python 中创建列表。

# 传统方式
numbers = [1, 2, 3, 4, 5]
squares = []
for num in numbers:
    squares.append(num ** 2)
print(squares)  # 输出: [1, 4, 9, 16, 25]
 
# 使用列表推导式
squares = [num ** 2 for num in numbers]
print(squares)  # 输出: [1, 4, 9, 16, 25]

函数

Python 中的函数允许您封装可重用的代码。

# 定义函数
def greet(name):
    print(f"你好, {name}!")
 
# 调用函数
greet("Alice")  # 输出: 你好, Alice!
 
# 带有返回值的函数
def add_numbers(a, b):
    return a + b
 
result = add_numbers(3, 4)
print(result)  # 输出: 7

模块和包

Python 的模块化设计允许您组织您的代码。这里是中文翻译版本:

# 导入一个模块
import math
print(math.pi)  # 输出: 3.141592653589793
 
# 从一个模块中导入特定的函数
from math import sqrt
print(sqrt(16))  # 输出: 4.0
 
# 使用别名导入一个模块
import numpy as np
print(np.array([1, 2, 3]))  # 输出: [1 2 3]

结论

在本教程中,您已经学习了 Python 中各种数据结构,包括列表、元组、字典和集合。您还探索了控制流语句、函数以及 Python 的模块化设计。这些概念是编写有效和高效的 Python 代码的基础。随着您不断学习和实践,您将能够利用这些工具构建更复杂和强大的应用程序。

MoeNagy Dev.