Pandas筛选含abc且不含pg的行:代码逻辑问题排查
问题分析与解决
问题场景
给定如下DataFrame:
import pandas as pd df = pd.DataFrame({'col1': ['abc-01', 'fft-a', 'abc-02'], 'col2': ['xyz-1', 'pg-02', 'fft-b'], 'col3': ['pg-77', 'zzz-1', 'abc-03']}) print(df)
输出结果:
col1 col2 col3 0 abc-01 xyz-1 pg-77 1 fft-a pg-02 zzz-1 2 abc-02 fft-b abc-03
需求是:保留**至少包含一个abc且同时不包含任何pg**的行,预期仅保留索引为2的行。
但以下代码未能过滤掉索引0的行:
final = df.loc[df.apply(lambda x:(x.str.contains('abc')) & (~x.str.contains('pg'))).any(axis=1)] print(final)
输出结果:
col1 col2 col3 0 abc-01 xyz-1 pg-77 2 abc-02 fft-b abc-03
错误原因分析
你的逻辑错误在于混淆了元素级条件和行级整体条件:
(x.str.contains('abc')) & (~x.str.contains('pg'))是对每个元素做判断,要求该元素同时满足“包含abc”和“不包含pg”- 后续的
.any(axis=1)只要行内有一个元素符合这个子条件,就会保留整行
索引0的行中,col1的abc-01满足元素级的子条件,所以.any(axis=1)返回True,导致整行被保留——但实际上这行的col3包含pg,违反了“整行不包含任何pg”的核心要求。
你的需求本质是两个独立行级条件的与操作:
- 行内至少有一个元素包含
abc - 行内所有元素都不包含
pg
正确实现
分开定义两个行级条件,再用&组合:
# 条件1:行内至少有一个元素包含abc has_abc = df.apply(lambda x: x.str.contains('abc').any(), axis=1) # 条件2:行内所有元素都不包含pg no_pg = df.apply(lambda x: ~x.str.contains('pg').any(), axis=1) final = df.loc[has_abc & no_pg] print(final)
也可以写成更简洁的链式写法:
final = df.loc[(df.apply(lambda x: x.str.contains('abc').any(), axis=1)) & (~df.apply(lambda x: x.str.contains('pg').any(), axis=1))] print(final)
输出结果符合预期:
col1 col2 col3 2 abc-02 fft-b abc-03
内容的提问来源于stack exchange,提问作者VERBOSE
相关产品推荐
相关产品推荐

