
在使用 pandas 处理结构化数据时,“选取特定值所在的行” 是最高频的操作之一 —— 无论是筛选 “性别为男的用户”“销售额超过 1000 的订单”,还是 “包含‘北京’的城市数据”,本质都是从 DataFrame 中精准定位符合条件的行。pandas 提供了多种灵活的筛选工具,从基础的布尔索引到进阶的 query 方法,覆盖从简单到复杂的所有场景。本文将从实际应用出发,拆解 6 类核心筛选方法,结合代码示例与场景对比,帮助读者快速掌握 “按需选行” 的技巧,提升数据处理效率。
在深入方法前,需先明确 “选行” 的核心价值 —— 它是数据清洗、子集分析、业务洞察的前置步骤:
子集分析:聚焦特定群体(如 “会员用户”“一线城市订单”),深入分析其特征;
业务决策:定位关键业务数据(如 “退款金额> 5000 的订单”),支撑问题排查与策略制定。
例如,电商平台分析 “高价值用户” 时,需先筛选 “近 30 天消费 > 5000 且购买次数 > 3” 的用户行;医疗数据分析 “糖尿病患者” 时,需筛选 “血糖值 > 7.0” 的患者行 —— 这些场景都依赖精准的 “选行” 操作。
pandas 选取特定行的本质是 “通过索引或条件,从 DataFrame 中提取满足要求的行子集”,核心依赖 3 类逻辑,所有方法均基于此扩展:
后续所有方法均围绕这 3 类逻辑展开,其中布尔索引是 “选特定值所在行” 的核心,需重点掌握。
根据 “筛选条件的复杂度”,将 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)
适用场景:已知目标列的 “精确值”,如选取 “会员等级 = VIP”“城市 = 北京朝阳” 的行,核心用布尔索引 +== 实现。
# 选取会员等级为"VIP"的行
vip_users = df[df["会员等级"] == "VIP"]
# 或用loc(更推荐,支持后续列筛选)
vip_users_loc = df.loc[df["会员等级"] == "VIP"]
print("VIP用户数据:")
print(vip_users_loc)
若需选取 “城市属于北京或上海” 的行,用isin() 函数(替代多个 ==+|,更简洁):
# 选取城市为"北京朝阳"或"北京海淀"或"上海浦东"或"上海静安"的行
bj_sh_users = df[df["城市"].isin(["北京朝阳", "北京海淀", "上海浦东", "上海静安"])]
# 或简化为“包含北京/上海”的城市(后续模糊匹配会讲更灵活的方式)
print("北京/上海用户数据:")
print(bj_sh_users)
字符串匹配需加引号(""),数值匹配无需(如df[df["年龄"] == 25]
);
避免用==
匹配浮点数(如df[df["消费金额"] == 3500.0]
),因浮点精度可能导致匹配失败,建议用between()
(见方法 3)。
适用场景:目标列是文本类型,需 “包含特定字符”,如选取 “城市包含北京”“姓名包含张” 的行,核心用str.contains() 实现。
# 选取城市名称中包含"北京"的行(不区分大小写,加case=False)
bj_users = df[df["城市"].str.contains("北京", case=False)]
# 若需“不包含”,加~(取反)
non_bj_users = df[~df["城市"].str.contains("北京")]
print("北京用户数据:")
print(bj_users)
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)]
)。
适用场景:目标列是数值类型,需 “在某个范围”,如选取 “年龄 25-30 岁”“消费金额 5000-10000” 的行,核心用between() 或比较运算符(>、<、>=、<=) 实现。
# 选取年龄在25到30岁之间的用户(包含25和30)
age_range_users = df[df["年龄"].between(25, 30)]
print("25-30岁用户数据:")
print(age_range_users)
# 选取消费金额大于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=False
或right=False
(如df["年龄"].between(25, 30, left=False)
)。
适用场景:需同时满足 “多个不同类型条件”,如选取 “VIP 会员且消费金额 > 6000 且年龄 < 40” 的行,核心用布尔索引 +&/| 组合条件。
# 条件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]
适用场景:数据清洗时,需定位 “缺失值所在行”(如 “消费金额为 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)
适用场景:多条件筛选时,用 query () 可直接写 “类 SQL 的条件表达式”,比布尔索引更简洁,尤其适合复杂逻辑。
# 选取VIP会员且消费金额>6000的用户(条件直接写字符串,无需df["列名"])
vip_high_spend = df.query("会员等级 == 'VIP' and 消费金额 > 6000")
print("VIP高消费用户(query方法):")
print(vip_high_spend)
若需用外部变量(如平均年龄)作为条件,用@变量名
引用:
avg_age = df["年龄"].mean() # 计算平均年龄(约32.83)
# 选取年龄大于平均年龄的普通会员
above_avg_age = df.query("年龄 > @avg_age and 会员等级 == '普通'")
print(f"年龄大于平均值({avg_age:.2f})的普通会员:")
print(above_avg_age)
字符串值需加单引号(如'VIP'
),数值无需;
支持复杂逻辑(如or
、in
,如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)
输出结果:
最终筛选的高价值用户:
  用户ID 姓名 城市 年龄 消费金额 会员等级
0 102 李四 上海浦东 32 8200 VIP
1 104 赵六 北京海淀 45 9500 VIP
在选取特定行时,新手常因 “数据类型”“逻辑运算符”“缺失值” 等问题导致筛选失败,以下是高频误区的解决方案:
现象:如 “消费金额” 列是字符串类型(如"3500"
),用df[df["消费金额"] > 5000]
筛选无结果。
解决方案:先转换数据类型:
# 查看数据类型
print(df["消费金额"].dtype) # 若为object(字符串),需转换为int/float
df["消费金额"] = pd.to_numeric(df["消费金额"], errors="coerce") # errors="coerce"将非数值转为NaN
and/or
替代&/|
导致报错现象:多条件用df[(df["年龄"]>25) and (df["会员等级"]=="VIP")]
,报错ValueError
。
原因:pandas 布尔索引需用 “按位运算符”&
(且)、|
(或),而非 Python 的逻辑运算符and/or
。
解决方案:替换为&/|
,且每个条件加括号:
correct_df = df[(df["年龄"]>25) & (df["会员等级"]=="VIP")] # 正确
现象:若 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]
现象:列含 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 中 “选取特定值所在行” 的所有场景,从数据筛选到结果处理形成完整闭环,为后续分析与决策提供精准的数据支撑。
Pandas 选取特定值所在行:6 类核心方法与实战指南 在使用 pandas 处理结构化数据时,“选取特定值所在的行” 是最高频的操作之 ...
2025-09-30球面卷积神经网络(SCNN) 为解决这一痛点,球面卷积神经网络(Spherical Convolutional Neural Network, SCNN) 应运而生。它通 ...
2025-09-30在企业日常运营中,“未来会怎样” 是决策者最关心的问题 —— 电商平台想知道 “下月销量能否达标”,金融机构想预判 “下周股 ...
2025-09-30Excel 能做聚类分析吗?基础方法、进阶技巧与场景边界 在数据分析领域,聚类分析是 “无监督学习” 的核心技术 —— 无需预设分 ...
2025-09-29XGBoost 决策树:原理、优化与工业级实战指南 在机器学习领域,决策树因 “可解释性强、处理非线性关系能力突出” 成为基础模型 ...
2025-09-29在标签体系的落地链路中,“设计标签逻辑” 只是第一步,真正让标签从 “纸上定义” 变为 “业务可用资产” 的关键,在于标签加 ...
2025-09-29在使用 Excel 数据透视表进行多维度数据汇总时,折叠功能是梳理数据层级的核心工具 —— 通过点击 “+/-” 符号可展开明细数据或 ...
2025-09-28在使用 Pandas 处理 CSV、TSV 等文本文件时,“引号” 是最容易引发格式混乱的 “隐形杀手”—— 比如字段中包含逗号(如 “北京 ...
2025-09-28在 CDA(Certified Data Analyst)数据分析师的技能工具箱中,数据查询语言(尤其是 SQL)是最基础、也最核心的 “武器”。无论 ...
2025-09-28Cox 模型时间依赖性检验:原理、方法与实战应用 在生存分析领域,Cox 比例风险模型(Cox Proportional Hazards Model)是分析 “ ...
2025-09-26检测因子类型的影响程度大小:评估标准、实战案例与管控策略 在检测分析领域(如环境监测、食品质量检测、工业产品合规性测试) ...
2025-09-26CDA 数据分析师:以数据库为基石,筑牢数据驱动的 “源头防线” 在数据驱动业务的链条中,“数据从哪里来” 是 CDA(Certified D ...
2025-09-26线性相关点分布的四种基本类型:特征、识别与实战应用 在数据分析与统计学中,“线性相关” 是描述两个数值变量间关联趋势的核心 ...
2025-09-25深度神经网络神经元个数确定指南:从原理到实战的科学路径 在深度神经网络(DNN)的设计中,“神经元个数” 是决定模型性能的关 ...
2025-09-25在企业数字化进程中,不少团队陷入 “指标困境”:仪表盘上堆砌着上百个指标,DAU、转化率、营收等数据实时跳动,却无法回答 “ ...
2025-09-25MySQL 服务器内存碎片:成因、检测与内存持续增长的解决策略 在 MySQL 运维中,“内存持续增长” 是常见且隐蔽的性能隐患 —— ...
2025-09-24人工智能重塑工程质量检测:核心应用、技术路径与实践案例 工程质量检测是保障建筑、市政、交通、水利等基础设施安全的 “最后一 ...
2025-09-24CDA 数据分析师:驾驭通用与场景指标,解锁数据驱动的精准路径 在数据驱动业务的实践中,指标是连接数据与决策的核心载体。但并 ...
2025-09-24在数据驱动的业务迭代中,AB 实验系统(负责验证业务优化效果)与业务系统(负责承载用户交互与核心流程)并非独立存在 —— 前 ...
2025-09-23CDA 业务数据分析:6 步闭环,让数据驱动业务落地 在企业数字化转型中,CDA(Certified Data Analyst)数据分析师的核心价值,并 ...
2025-09-23