数据过滤 #

数据过滤概述 #

数据过滤是数据分析中最常用的操作之一,Pandas 提供了多种灵活的过滤方法。

text
┌─────────────────────────────────────────────────────────────┐
│                    数据过滤方法                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  布尔索引                                                   │
│  ├── 比较运算符:==, !=, >, <, >=, <=                      │
│  ├── 逻辑运算符:&, |, ~                                    │
│  └── isin(), between()                                     │
│                                                             │
│  字符串过滤                                                 │
│  ├── str.contains()                                        │
│  ├── str.startswith() / str.endswith()                     │
│  └── str.match()                                           │
│                                                             │
│  查询语法                                                   │
│  └── df.query('expression')                                │
│                                                             │
│  高级过滤                                                   │
│  ├── where() / mask()                                      │
│  ├── filter()                                              │
│  └── 自定义函数                                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

准备数据 #

python
import pandas as pd
import numpy as np

np.random.seed(42)
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank', 'Grace', 'Henry'],
    'age': [25, 30, 35, 28, 32, 45, 29, 38],
    'city': ['New York', 'London', 'Tokyo', 'Paris', 'Berlin', 'London', 'Tokyo', 'New York'],
    'department': ['Sales', 'Engineering', 'Engineering', 'Sales', 'Marketing', 'Engineering', 'Sales', 'Marketing'],
    'salary': [50000, 70000, 80000, 55000, 60000, 90000, 52000, 75000],
    'performance': [85, 92, 88, 78, 90, 95, 82, 87]
})

print(df)

基本条件过滤 #

比较运算符 #

python
# 等于
print(df[df['age'] == 30])

# 不等于
print(df[df['department'] != 'Sales'])

# 大于
print(df[df['salary'] > 70000])

# 小于
print(df[df['age'] < 30])

# 大于等于
print(df[df['performance'] >= 90])

# 小于等于
print(df[df['salary'] <= 55000])

多条件过滤 #

python
# 与条件(&)
print(df[(df['age'] > 30) & (df['salary'] > 70000)])

# 或条件(|)
print(df[(df['age'] < 28) | (df['age'] > 40)])

# 非条件(~)
print(df[~(df['department'] == 'Sales')])

# 复杂条件
print(df[(df['department'] == 'Engineering') & 
          ((df['salary'] > 75000) | (df['performance'] > 90))])

注意运算符优先级 #

python
# 错误:Python 会将 df['age'] > 30 & df['salary'] > 70000 解析错误
# df[df['age'] > 30 & df['salary'] > 70000]  # 报错

# 正确:使用括号
print(df[(df['age'] > 30) & (df['salary'] > 70000)])

isin 方法 #

基本用法 #

python
# 选择特定值
cities = ['New York', 'London']
print(df[df['city'].isin(cities)])

# 选择特定部门
departments = ['Engineering', 'Marketing']
print(df[df['department'].isin(departments)])

# 取反
print(df[~df['city'].isin(['New York', 'London'])])

结合其他条件 #

python
# isin + 其他条件
print(df[df['city'].isin(['New York', 'London']) & (df['salary'] > 60000)])

between 方法 #

python
# 数值范围
print(df[df['age'].between(30, 40)])
# 等价于
print(df[(df['age'] >= 30) & (df['age'] <= 40)])

# 包含边界
print(df[df['salary'].between(60000, 80000, inclusive='both')])  # 默认
print(df[df['salary'].between(60000, 80000, inclusive='neither')])
print(df[df['salary'].between(60000, 80000, inclusive='left')])
print(df[df['salary'].between(60000, 80000, inclusive='right')])

字符串过滤 #

contains 方法 #

python
# 包含子串
print(df[df['name'].str.contains('a')])
print(df[df['name'].str.contains('a', case=False)])  # 不区分大小写

# 正则表达式
print(df[df['name'].str.contains(r'^[AB]')])  # 以 A 或 B 开头
print(df[df['name'].str.contains(r'e$')])     # 以 e 结尾

startswith / endswith #

python
# 开头匹配
print(df[df['name'].str.startswith('A')])

# 结尾匹配
print(df[df['name'].str.endswith('e')])

# 多个匹配
print(df[df['name'].str.startswith(('A', 'B'))])

match 方法 #

python
# 正则匹配
print(df[df['name'].str.match(r'[AB]')])  # 以 A 或 B 开头
print(df[df['name'].str.match(r'.*ie.*')])  # 包含 ie

字符串长度 #

python
# 长度过滤
print(df[df['name'].str.len() > 5])

query 方法 #

基本语法 #

python
# 简单条件
print(df.query('age > 30'))

# 多条件
print(df.query('age > 30 and salary > 70000'))
print(df.query('age > 30 & salary > 70000'))  # 等价

# 或条件
print(df.query('age < 28 or age > 40'))

# 取反
print(df.query('not (department == "Sales")'))

使用变量 #

python
# 使用 @ 引用变量
min_salary = 70000
target_dept = 'Engineering'

print(df.query('salary > @min_salary'))
print(df.query('department == @target_dept'))

in 操作 #

python
# in 操作
print(df.query('city in ["New York", "London"]'))

# not in
print(df.query('city not in ["New York", "London"]'))

索引查询 #

python
# 设置索引名
df_indexed = df.copy()
df_indexed.index.name = 'id'

# 查询索引
print(df_indexed.query('id in [0, 2, 4]'))

字符串方法 #

python
# 字符串方法
print(df.query('name.str.contains("a")'))
print(df.query('name.str.startswith("A")'))

where 和 mask #

where 方法 #

python
# where - 保留满足条件的值,其他变为 NaN
print(df.where(df['salary'] > 70000))

# 指定替换值
print(df.where(df['salary'] > 70000, other=0))

# 只对特定列操作
print(df[['salary', 'performance']].where(df['salary'] > 70000, other=0))

mask 方法 #

python
# mask - 与 where 相反,保留不满足条件的值
print(df.mask(df['salary'] > 70000))

# 指定替换值
print(df.mask(df['salary'] > 70000, other='High Salary'))

filter 方法 #

python
# 按列名过滤
print(df.filter(like='name'))  # 包含 name 的列
print(df.filter(like='a'))     # 包含 a 的列

# 正则表达式
print(df.filter(regex='^[a-z]'))  # 以小写字母开头的列

# 按项过滤
print(df.filter(items=['name', 'age', 'salary']))

# 按行过滤
print(df.filter(like='0', axis=0))  # 索引包含 0 的行

高级过滤技巧 #

使用函数 #

python
# 使用 apply
print(df[df.apply(lambda row: row['salary'] / row['age'] > 2000, axis=1)])

# 使用自定义函数
def filter_func(row):
    return row['salary'] > 60000 and row['performance'] > 85

print(df[df.apply(filter_func, axis=1)])

使用 np.where #

python
import numpy as np

# 创建条件列
df['salary_level'] = np.where(df['salary'] > 70000, 'High', 'Low')
print(df)

使用 np.select #

python
# 多条件分类
conditions = [
    df['performance'] >= 90,
    df['performance'] >= 80,
    df['performance'] >= 70
]
choices = ['Excellent', 'Good', 'Average']
df['rating'] = np.select(conditions, choices, default='Poor')
print(df)

使用 pd.cut #

python
# 分箱
df['age_group'] = pd.cut(df['age'], 
                          bins=[0, 30, 40, 100], 
                          labels=['Young', 'Middle', 'Senior'])
print(df)

# 按分箱过滤
print(df[df['age_group'] == 'Young'])

使用 pd.qcut #

python
# 等频分箱
df['salary_quartile'] = pd.qcut(df['salary'], q=4, labels=['Q1', 'Q2', 'Q3', 'Q4'])
print(df)

# 按分位数过滤
print(df[df['salary_quartile'] == 'Q4'])

缺失值过滤 #

python
# 创建带缺失值的数据
df_na = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, np.nan, 8],
    'C': [9, 10, 11, 12]
})

# 过滤包含缺失值的行
print(df_na[df_na['A'].notna()])
print(df_na.dropna())

# 过滤不包含缺失值的行
print(df_na[df_na.isna().any(axis=1)])

# 过滤特定列有缺失值的行
print(df_na[df_na['B'].isna()])

重复值过滤 #

python
# 创建带重复值的数据
df_dup = pd.DataFrame({
    'A': [1, 1, 2, 2, 3],
    'B': ['a', 'a', 'b', 'b', 'c']
})

# 过滤重复行
print(df_dup[~df_dup.duplicated()])

# 保留最后一个
print(df_dup[~df_dup.duplicated(keep='last')])

# 按特定列判断
print(df_dup[~df_dup.duplicated(subset=['A'])])

性能优化 #

使用 isin 替代多个 or #

python
# 慢
print(df[(df['city'] == 'New York') | 
          (df['city'] == 'London') | 
          (df['city'] == 'Tokyo')])

# 快
print(df[df['city'].isin(['New York', 'London', 'Tokyo'])])

使用 query 处理复杂条件 #

python
# 复杂条件使用 query 更清晰
print(df.query('age > 30 and salary > 70000 and department in ["Engineering", "Marketing"]'))

避免链式操作 #

python
# 不推荐
result = df[df['age'] > 30][['name', 'salary']]

# 推荐
result = df.loc[df['age'] > 30, ['name', 'salary']]

过滤方法选择指南 #

text
┌─────────────────────────────────────────────────────────────┐
│                    过滤方法选择                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  场景                      推荐方法                         │
│  ────────────────────────  ────────────────────────────    │
│  单条件                    df[df['col'] > value]            │
│  多条件(与/或)           df[(cond1) & (cond2)]            │
│  特定值列表                df[df['col'].isin(values)]       │
│  范围                      df[df['col'].between(a, b)]      │
│  字符串匹配                df[df['col'].str.contains()]     │
│  复杂条件                  df.query('...')                  │
│  函数过滤                  df[df.apply(func, axis=1)]       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

下一步 #

掌握了数据过滤后,接下来学习 数据清洗,了解如何处理缺失值、重复值和异常值!

最后更新:2026-04-04