Pandas查找指定字符串包含多列值的DataFrame行
Pandas筛选列值为指定字符串子串的行
原代码问题分析
你写的代码存在两个核心问题:
- 错误地将Python原生字符串的
find()方法直接作用于Pandas Series ——find()仅接受单个字符串参数,无法处理Series类型的批量数据。 - 括号逻辑混乱,条件判断的优先级和闭合规则都不符合语法要求。
正确实现方式
我们需要逐行检查CITY、DISTRICT、STREET的列值是否是目标字符串s的子串,再将三个条件的结果取交集。以下是两种可靠的实现方法:
方法1:用apply()逐行验证(推荐)
这种方式直观易懂,无需处理正则转义,适合包含空格或特殊字符的列值:
import pandas as pd s = "Bad Testcity Teststr." # 构建筛选条件:排除空值 + 列值是s的子串 condition = ( df['CITY'].notna() & df['CITY'].apply(lambda x: x in s) & df['DISTRICT'].notna() & df['DISTRICT'].apply(lambda x: x in s) & df['STREET'].notna() & df['STREET'].apply(lambda x: x in s) ) # 筛选符合条件的行 df_res = df.loc[condition]
方法2:用正则匹配实现反向str.contains
如果偏好使用Pandas的字符串方法,可以通过构造正则实现反向匹配(需注意转义特殊字符):
import pandas as pd import re s = "Bad Testcity Teststr." # 对每个列值构造正则,检查s是否包含该值 def check_substring(col): return col.apply(lambda x: pd.Series(s).str.contains(re.escape(x), regex=True).iloc[0] if pd.notna(x) else False) condition = ( check_substring(df['CITY']) & check_substring(df['DISTRICT']) & check_substring(df['STREET']) ) df_res = df.loc[condition]
示例验证
针对你提供的DataFrame,s="Bad Testcity Teststr."包含所有目标行的CITY(Bad Testcity)、DISTRICT(Bad Testcity)、STREET(Teststr.),上述代码会准确筛选出ID为4025217、4025219、4025242等符合条件的行。
注意事项
- 必须通过
notna()过滤空值,否则x in s会因NaN非字符串类型引发错误。 - 若列值包含
.、*等正则特殊字符,方法2需用re.escape()转义,方法1则无需额外处理。
内容的提问来源于stack exchange,提问作者Isolde Maduschn
相关产品推荐
相关产品推荐

