热线电话:13121318867

登录
首页大数据时代【CDA干货】Pandas 选取特定值所在行:6 类核心方法与实战指南
【CDA干货】Pandas 选取特定值所在行:6 类核心方法与实战指南
2025-09-30
收藏

Pandas 选取特定值所在行:6 类核心方法与实战指南

在使用 pandas 处理结构化数据时,“选取特定值所在的行” 是最高频的操作之一 —— 无论是筛选 “性别为男的用户”“销售额超过 1000 的订单”,还是 “包含‘北京’的城市数据”,本质都是从 DataFrame 中精准定位符合条件的行。pandas 提供了多种灵活的筛选工具,从基础的布尔索引到进阶的 query 方法,覆盖从简单到复杂的所有场景。本文将从实际应用出发,拆解 6 类核心筛选方法,结合代码示例与场景对比,帮助读者快速掌握 “按需选行” 的技巧,提升数据处理效率。

一、基础认知:为什么 “选取特定行” 是数据分析的核心?

在深入方法前,需先明确 “选行” 的核心价值 —— 它是数据清洗、子集分析、业务洞察的前置步骤:

  • 数据清洗:筛选出缺失值异常值所在的行(如 “年龄> 150” 的异常数据),进行修正或删除;

  • 子集分析:聚焦特定群体(如 “会员用户”“一线城市订单”),深入分析其特征

  • 业务决策:定位关键业务数据(如 “退款金额> 5000 的订单”),支撑问题排查与策略制定。

例如,电商平台分析 “高价值用户” 时,需先筛选 “近 30 天消费 > 5000 且购买次数 > 3” 的用户行;医疗数据分析 “糖尿病患者” 时,需筛选 “血糖值 > 7.0” 的患者行 —— 这些场景都依赖精准的 “选行” 操作。

二、核心工具:pandas 选行的 3 个基础逻辑

pandas 选取特定行的本质是 “通过索引或条件,从 DataFrame 中提取满足要求的行子集”,核心依赖 3 类逻辑,所有方法均基于此扩展:

  1. 标签索引(loc):通过行标签(如索引名称、字符串标签)选行,支持条件表达式;

  2. 位置索引(iloc):通过行的位置(如第 1 行、第 10 行)选行,仅支持整数位置;

  3. 布尔索引:通过 “每行是否满足条件” 的布尔值(True/False)选行,是最灵活的选行逻辑。

后续所有方法均围绕这 3 类逻辑展开,其中布尔索引是 “选特定值所在行” 的核心,需重点掌握。

三、6 类核心方法:从简单到复杂的选行实战

根据 “筛选条件的复杂度”,将 pandas 选行方法分为 6 类,每类均配代码示例(基于 Python 3.9+、pandas 1.5+),数据示例统一使用以下电商用户 DataFrame

import pandas as pd

# 构造示例数据

data = {

   "用户ID": [101, 102, 103, 104, 105, 106],

   "姓名": ["张三""李四""王五""赵六""孙七""周八"],

   "城市": ["北京朝阳""上海浦东""广州天河""北京海淀""深圳南山""上海静安"],

   "年龄": [25, 32, 28, 45, 36, 29],

   "消费金额": [3500, 8200, 4800, 9500, 6300, 2800],

   "会员等级": ["普通""VIP""普通""VIP""VIP""普通"]

}

df = pd.DataFrame(data)

print("原始数据:")

print(df)

1. 方法 1:精确匹配 —— 选取某列等于特定值的行

适用场景:已知目标列的 “精确值”,如选取 “会员等级 = VIP”“城市 = 北京朝阳” 的行,核心用布尔索引 +== 实现。

代码示例 1:单条件精确匹配(会员等级 = VIP)

# 选取会员等级为"VIP"的行

vip_users = df[df["会员等级"] == "VIP"]

# 或用loc(更推荐,支持后续列筛选)

vip_users_loc = df.loc[df["会员等级"] == "VIP"]

print("VIP用户数据:")

print(vip_users_loc)

代码示例 2:多值精确匹配(城市在指定列表中)

若需选取 “城市属于北京或上海” 的行,用isin() 函数(替代多个 ==+|,更简洁):

# 选取城市为"北京朝阳"或"北京海淀"或"上海浦东"或"上海静安"的行

bj_sh_users = df[df["城市"].isin(["北京朝阳""北京海淀""上海浦东""上海静安"])]

# 或简化为“包含北京/上海”的城市(后续模糊匹配会讲更灵活的方式)

print("北京/上海用户数据:")

print(bj_sh_users)

关键说明:

  • 字符串匹配需加引号(""),数值匹配无需(如df[df["年龄"] == 25]);

  • 避免用==匹配浮点数(如df[df["消费金额"] == 3500.0]),因浮点精度可能导致匹配失败,建议用between()(见方法 3)。

2. 方法 2:模糊匹配 —— 选取某列包含特定字符的行

适用场景:目标列是文本类型,需 “包含特定字符”,如选取 “城市包含北京”“姓名包含张” 的行,核心用str.contains() 实现。

代码示例 1:包含特定字符(城市包含 "北京")

# 选取城市名称中包含"北京"的行(不区分大小写,加case=False)

bj_users = df[df["城市"].str.contains("北京"case=False)]

# 若需“不包含”,加~(取反)

non_bj_users = df[~df["城市"].str.contains("北京")]

print("北京用户数据:")

print(bj_users)

代码示例 2:模糊匹配 + 正则(城市以 "北京" 开头)

str.contains () 支持正则表达式,如选取 “城市以北京开头”(排除 “北京朝阳”“北京海淀” 外的其他北京区域):

正则表达式:^表示开头,$表示结尾

bj_start_users = df[df["城市"].str.contains("^北京", regex=True)]

print("城市以北京开头的用户:")

print(bj_start_users)

关键说明:

  • 处理缺失值:若列含 NaN,需加na=False(避免返回 NaN 导致筛选错误),如df[df["城市"].str.contains("北京", na=False)]

  • 正则开关:默认regex=True,若需匹配 “包含 * 或.” 等特殊字符,需加regex=False(如df[df["城市"].str.contains("*", regex=False)])。

3. 方法 3:范围匹配 —— 选取某列在特定区间的行

适用场景:目标列是数值类型,需 “在某个范围”,如选取 “年龄 25-30 岁”“消费金额 5000-10000” 的行,核心用between()比较运算符(>、<、>=、<=) 实现。

代码示例 1:用 between () 匹配闭区间(年龄 25≤x≤30)

# 选取年龄在25到30岁之间的用户(包含25和30)

age_range_users = df[df["年龄"].between(25, 30)]

print("25-30岁用户数据:")

print(age_range_users)

代码示例 2:用比较运算符匹配开区间(消费金额 > 5000 且 < 10000)

# 选取消费金额大于5000且小于10000的用户(注意用&,且每个条件加括号)

high_spend_users = df[(df["消费金额"] > 5000) & (df["消费金额"] < 10000)]

# 若用或逻辑,用|(如消费金额<3000或>8000)

print("高消费用户数据(5000<金额<10000):")

print(high_spend_users)

关键说明:

  • 多条件用&(且)、|(或),必须加括号(因运算符优先级问题);

  • between () 默认包含边界(left=True, right=True),如需开区间,设left=Falseright=False(如df["年龄"].between(25, 30, left=False))。

4. 方法 4:多条件组合 —— 同时满足多个筛选规则

适用场景:需同时满足 “多个不同类型条件”,如选取 “VIP 会员且消费金额 > 6000 且年龄 < 40” 的行,核心用布尔索引 +&/| 组合条件。

代码示例:多条件组合筛选(VIP + 高消费 + 年轻用户)

# 条件1:会员等级=VIP;条件2:消费金额>6000;条件3:年龄<40

high_value_vip = df[

   (df["会员等级"] == "VIP") &

   (df["消费金额"] > 6000) &

   (df["年龄"] < 40)

]

# 用loc同时筛选行和列(只保留用户ID、姓名、消费金额)

high_value_vip_cols = df.loc[

   (df["会员等级"] == "VIP") &

   (df["消费金额"] > 6000) &

   (df["年龄"] < 40),

   ["用户ID""姓名""消费金额"]  # 仅保留需要的列

]

print("高价值年轻VIP用户:")

print(high_value_vip_cols)

关键说明:

  • 不同列的条件可自由组合(文本精确匹配 + 数值范围匹配);

  • 若条件复杂,建议先定义每个条件变量,再组合(提高可读性):

cond1 = df["会员等级"] == "VIP"

cond2 = df["消费金额"] > 6000

cond3 = df["年龄"] < 40

high_value_vip = df[cond1 & cond2 & cond3]

5. 方法 5:按缺失值筛选 —— 选取某列有 / 无缺失值的行

适用场景数据清洗时,需定位 “缺失值所在行”(如 “消费金额为 NaN”)或 “无缺失值的行”,核心用isna()/notna() 实现。

代码示例:

# 先构造含缺失值的数据(模拟实际场景)

df_with_na = df.copy()

df_with_na.loc[2, "消费金额"] = None  # 第3行(索引2)消费金额设为NaN

df_with_na.loc[4, "城市"] = None     # 第5行(索引4)城市设为NaN

# 1. 选取消费金额有缺失值的行

na_spend_users = df_with_na[df_with_na["消费金额"].isna()]

# 2. 选取城市无缺失值的行

non_na_city_users = df_with_na[df_with_na["城市"].notna()]

print("消费金额有缺失的用户:")

print(na_spend_users)

print("城市无缺失的用户:")

print(non_na_city_users)

6. 方法 6:高级筛选 —— 用 query () 简化复杂条件

适用场景:多条件筛选时,用 query () 可直接写 “类 SQL 的条件表达式”,比布尔索引更简洁,尤其适合复杂逻辑。

代码示例 1:基础 query 筛选(VIP 且消费金额 > 6000)

# 选取VIP会员且消费金额>6000的用户(条件直接写字符串,无需df["列名"])

vip_high_spend = df.query("会员等级 == 'VIP' and 消费金额 > 6000")

print("VIP高消费用户(query方法):")

print(vip_high_spend)

代码示例 2:query 引用外部变量(筛选年龄大于平均年龄的用户)

若需用外部变量(如平均年龄)作为条件,用@变量名引用:

avg_age = df["年龄"].mean()  # 计算平均年龄(约32.83)

# 选取年龄大于平均年龄的普通会员

above_avg_age = df.query("年龄 > @avg_age and 会员等级 == '普通'")

print(f"年龄大于平均值({avg_age:.2f})的普通会员:")

print(above_avg_age)

关键说明:

  • 字符串值需加单引号(如'VIP'),数值无需;

  • 支持复杂逻辑(如orin,如query("城市 in ['北京朝阳', '上海浦东']"))。

四、实战案例:综合筛选与结果处理

结合上述方法,完成 “电商高价值用户分析” 的完整流程:筛选 “25-40 岁、消费金额 > 5000、城市包含‘北京’或‘上海’的 VIP 用户”,并导出结果。

# 步骤1:定义筛选条件

cond_city = df["城市"].str.contains("北京|上海", na=False)  # 城市含北京或上海

cond_age = df["年龄"].between(25, 40)                     # 年龄25-40岁

cond_spend = df["消费金额"] > 5000                        # 消费金额>5000

cond_vip = df["会员等级"] == "VIP"                        # 会员等级=VIP

# 步骤2:组合条件筛选

high_value_users = df[cond_city & cond_age & cond_spend & cond_vip]

# 步骤3:处理结果(重置索引,方便后续分析)

high_value_users = high_value_users.reset_index(drop=True)  # drop=True删除原索引

# 步骤4:导出结果(保存为Excel)

high_value_users.to_excel("高价值用户.xlsx", index=False)

print("最终筛选的高价值用户:")

print(high_value_users)

输出结果

最终筛选的高价值用户:

&#x20;  用户ID  姓名    城市  年龄  消费金额 会员等级

0   102  李四  上海浦东   32    8200    VIP

1   104  赵六  北京海淀   45    9500    VIP

五、常见误区与避坑指南

在选取特定行时,新手常因 “数据类型”“逻辑运算符”“缺失值” 等问题导致筛选失败,以下是高频误区的解决方案:

1. 误区 1:数据类型不匹配导致匹配失败

现象:如 “消费金额” 列是字符串类型(如"3500"),用df[df["消费金额"] > 5000]筛选无结果。

解决方案:先转换数据类型

# 查看数据类型

print(df["消费金额"].dtype)  # 若为object(字符串),需转换为int/float

df["消费金额"] = pd.to_numeric(df["消费金额"], errors="coerce")  # errors="coerce"将非数值转为NaN

2. 误区 2:用and/or替代&/|导致报错

现象:多条件用df[(df["年龄"]>25) and (df["会员等级"]=="VIP")],报错ValueError

原因pandas 布尔索引需用 “按位运算符”&(且)、|(或),而非 Python 的逻辑运算符and/or

解决方案:替换为&/|,且每个条件加括号:

correct_df = df[(df["年龄"]>25) & (df["会员等级"]=="VIP")]  # 正确

3. 误区 3:忽略索引重复导致 loc 筛选错误

现象:若 DataFrame 索引重复(如df.index = [0,1,0,3,4,5]),用loc[0]会返回所有索引为 0 的行,而非第一行。

解决方案:如需按位置选行,用 iloc;或重置索引

# 重置索引为连续整数

df_reset = df.reset_index(drop=True)

# 按位置选第1行(iloc)

first_row = df_reset.iloc[0]

4. 误区 4:模糊匹配时未处理缺失值

现象:列含 NaN 时,df[df["城市"].str.contains("北京")]会返回NaN,导致筛选结果包含错误行。

解决方案:加na=False,将 NaN 视为不匹配:

safe_df = df[df["城市"].str.contains("北京", na=False)]

六、总结:方法选择与效率对比

不同选行方法的适用场景与效率不同,需根据需求选择:

筛选场景 推荐方法 效率(数据量 100 万行) 关键优势
单条件精确匹配 布尔索引(df [df ["列"]== 值]) 快(~0.1 秒) 代码简洁,易上手
多值精确匹配 isin() 快(~0.2 秒) 替代多个 ==+
文本模糊匹配 str.contains() 中(~0.5 秒) 支持正则,灵活处理文本
数值范围匹配 between() 快(~0.1 秒) 避免浮点精度问题
复杂多条件 query() 中(~0.3 秒) SQL 语法,可读性高
缺失值筛选 isna()/notna() 快(~0.1 秒) 精准定位数据质量问题

核心建议

  • 日常分析优先用 “布尔索引 + isin ()/between ()”,兼顾效率与简洁;

  • 复杂条件(如引用外部变量、多列组合)用 query (),提升代码可读性;

  • 大数据量(千万级)筛选时,避免用 str.contains ()(正则匹配慢),可先预处理文本(如提取城市前缀)再用 isin ()。

通过掌握上述方法,可轻松应对 pandas 中 “选取特定值所在行” 的所有场景,从数据筛选到结果处理形成完整闭环,为后续分析与决策提供精准的数据支撑。

推荐学习书籍 《CDA一级教材》适合CDA一级考生备考,也适合业务及数据分析岗位的从业者提升自我。完整电子版已上线CDA网校,累计已有10万+在读~ !

免费加入阅读:https://edu.cda.cn/goods/show/3151?targetId=5147&preview=0

数据分析师资讯
更多

OK
客服在线
立即咨询
客服在线
立即咨询