pands中dataframe筛选操作

闹麻了兄弟们,好长时间没有更新了,这段时间忙疯了,没有沉淀,全是忙碌。现在更新pandas基础中的筛选操作,筛选还是很基础并且最常用的功能。

1. 准备示例数据

首先,我们创建一个示例 DataFrame,用于后续所有的操作演示。

import pandas as pd
import numpy as np

# 创建一个员工信息DataFrame
data = {
    '姓名': ['张三', '李四', '王五', '赵六', '钱七'],
    '部门': ['销售', '技术', '技术', '市场', '销售'],
    '年龄': [25, 32, 28, 45, 36],
    '工资': [50000, 85000, 70000, 60000, 90000],
    '入职年份': [2019, 2016, 2020, 2010, 2015]
}

df = pd.DataFrame(data)
print("原始数据集:")
print(df)

我们的 df 看起来会是这样的:

姓名 部门 年龄 工资 入职年份
0 张三 销售 25 50000 2019
1 李四 技术 32 85000 2016
2 王五 技术 28 70000 2020
3 赵六 市场 45 60000 2010
4 钱七 销售 36 90000 2015

2. 单条件筛选

单条件筛选的核心是使用布尔序列(Boolean Series)。我们通过对 DataFrame 的某一列施加条件判断,会得到一个由 TrueFalse 组成的序列。将这个布尔序列传递给 DataFrame,Pandas 就会返回所有对应 True 的行。

2.1 基本语法:df[df['列名'] <条件>]

# 筛选出所有"技术"部门的员工
condition = df['部门'] == '技术' # 这是一个布尔序列
tech_team = df[condition] # 将布尔序列传入df

# 通常我们会直接写成一行
tech_team = df[df['部门'] == '技术']
print("技术部员工:")
print(tech_team)

输出:

姓名 部门 年龄 工资 入职年份
1 李四 技术 32 85000 2016
2 王五 技术 28 70000 2020

2.2 常用的比较运算符:

  • ==:等于
  • !=:不等于
  • >:大于
  • <:小于
  • >=:大于等于
  • <=:小于等于
# 筛选出年龄大于30岁的员工
df[df['年龄'] > 30]

# 筛选出工资不等于85000的员工
df[df['工资'] != 85000]

2.3 使用 .isin() 方法进行多项匹配

当你想筛选某列的值在某个列表中出现时,用 isin() 非常方便。

# 筛选出部门是"销售"或"市场"的员工
df[df['部门'].isin(['销售', '市场'])]

2.4 处理空值:.isna().notna()

# 假设我们数据中有空值NaN
df_with_nan = df.copy()
df_with_nan.loc[2, '工资'] = np.nan

# 筛选出"工资"为空的行
df_with_nan[df_with_nan['工资'].isna()]

# 筛选出"工资"不为空的行
df_with_nan[df_with_nan['工资'].notna()]

3. 多条件筛选

多条件筛选需要将多个布尔序列进行组合。Pandas 使用以下符号进行逻辑操作:

  • & 表示逻辑与 (and):所有条件都满足
  • | 表示逻辑或 (or):至少一个条件满足
  • ~ 表示逻辑非 (not):取反

非常重要: 每个条件都必须用括号 () 括起来,因为 &| 的运算优先级高于 ==> 等比较运算符。

3.1 逻辑与 (&)

# 筛选出"技术部"且"年龄大于30岁"的员工
df[(df['部门'] == '技术') & (df['年龄'] > 30)]

输出:

姓名 部门 年龄 工资 入职年份
1 李四 技术 32 85000 2016

3.2 逻辑或 (|)

# 筛选出"工资大于80000"或"年龄小于30岁"的员工
df[(df['工资'] > 80000) | (df['年龄'] < 30)]

输出:

姓名 部门 年龄 工资 入职年份
0 张三 销售 25 50000 2019
1 李四 技术 32 85000 2016
4 钱七 销售 36 90000 2015

3.3 逻辑非 (~)

# 筛选出"不是销售部门"的员工
df[~(df['部门'] == '销售')]

# 等价于
df[df['部门'] != '销售']

4. 基于字符串方法的筛选 (.str.contains())

如果列中的值是字符串,可以使用 .str 访问器下的多种字符串方法进行模糊筛选。

# 筛选出姓名中包含"五"的员工 (模糊匹配)
df[df['姓名'].str.contains('五')]

# 默认是大小写敏感的,可以添加case=False参数忽略大小写
# df[df['姓名'].str.contains('Wang', case=False)]

5. 筛选后的常见操作

筛选出的结果仍然是一个 DataFrame,你可以对它进行任何对 DataFrame 的操作。

5.1 获取筛选后的行数据

方法一:使用 .loc.iloc (推荐)
.loc 通过标签索引,.iloc 通过位置索引。

# 先筛选出技术部员工,然后获取第一行(索引为1的那行)的所有数据
tech_df = df[df['部门'] == '技术']
li_si_info = tech_df.loc[1] # 获取索引标签为1的行
print(li_si_info)
print(f"李四的工资:{li_si_info['工资']}")

# 获取筛选后第一行(无论它的索引是什么)的所有数据
first_tech_info = tech_df.iloc[0] # iloc[0] 表示第0行
print(first_tech_info)

# 组合使用:直接定位到筛选后某个单元格的值
# 获取"技术部第一个员工"的"工资"
salary = tech_df.iloc[0]['工资']
salary = tech_df.iloc[0].loc['工资'] # 另一种写法

方法二:直接再筛选 (链式操作)
虽然可行,但代码可读性较差,且可能导致 SettingWithCopyWarning一般不推荐

# 不推荐:直接链式操作
df[df['部门'] == '技术'].iloc[0]['工资']

5.2 对筛选结果进行统计

# 计算技术部的平均工资
tech_salary_mean = df[df['部门'] == '技术']['工资'].mean()
print(f"技术部平均工资: {tech_salary_mean}")

# 计算销售部的最高年龄
sales_max_age = df[df['部门'] == '销售']['年龄'].max()

# 统计每个部门的人数 (这本身就是一个分组操作,但筛选也常用)
df[df['年龄'] > 30]['部门'].value_counts() # 年龄大于30岁的人在各部门的分布

5.3 修改筛选后的数据

这是一个非常重要的应用场景,通常使用 .loc 来避免警告。

# 给所有技术部员工加薪10%
df.loc[df['部门'] == '技术', '工资'] = df.loc[df['部门'] == '技术', '工资'] * 1.1
print("加薪后的数据集:")
print(df)

6. 其他有用的筛选方法:.query()

Pandas 提供了一个非常简洁的 query() 方法,允许你使用字符串表达式进行筛选,尤其适合复杂的多条件查询。

# 使用query完成多条件筛选
# 在query字符串中,列名可以不用加引号,但字符串值需要加引号
tech_senior = df.query('部门 == "技术" and 年龄 > 30')
print(tech_senior)

# 变量也可以传入
dept_name = "销售"
min_salary = 60000
result = df.query('部门 == @dept_name and 工资 >= @min_salary') # 使用@来引用外部变量
print(result)

总结与要点回顾

操作类型 方法/语法 备注
单条件 df[df['列'] > 10] 核心是生成布尔序列
多条件与 df[(条件1) & (条件2)] 每个条件必须用括号括起来!
多条件或 df[(条件1) | (条件2)] 每个条件必须用括号括起来!
多条件非 df[~(条件)]
列表匹配 df[df['列'].isin([列表])] 非常适合检查值是否在给定列表中
空值筛选 df[df['列'].isna()], df[df['列'].notna()] 用于数据清洗
字符串模糊 df[df['列'].str.contains('pattern')] 基于正则表达式的强大文本匹配
优雅查询 df.query('列a > 100 & 列b == "x"') 语法简洁,适合复杂查询,可引用外部变量(@var)
筛选后操作 df_filtered.iloc[0], df_filtered['列'].mean() 筛选结果是一个新DataFrame,可以对其进行任何操作
筛选后赋值 df.loc[df['列'] > 10, '列'] = 100 使用 .loc 安全地修改原数据,避免 SettingWithCopyWarning
文末声明:

您必须遵守关于,您可以随意转发/引用,但要注明原作者Leon或设置本文跳转连接,并且您必须在文中包含或提醒浏览者遵守作者声明
欢迎关注公众号获取第二手文章!高效工作法

暂无评论

发送评论 编辑评论


				
上一篇