如何筛选Pandas DataFrame中包含指定列表所有子串的行
解决DataFrame筛选包含所有指定子串行的问题
错误原因分析
你遇到的KeyError: False是因为:all([word in df.question for word in ['King', 'England']])中,word in df.question是将整个question列的Series与单个字符串比较,返回的是每行对应布尔值的Series,而all()会把这个Series压缩成一个单一的布尔值(比如False)。此时df[单一布尔值]会被当作列名去查找,DataFrame里没有名为False的列,因此报错。
正确筛选方法
以下几种方法都能实现“保留question列同时包含所有指定子串的行”:
方法1:逐行检查(直观易懂)
用apply对每行执行你验证过的all逻辑,生成筛选用的布尔掩码:
substrings = ['King', 'England'] # 生成每行是否包含所有子串的布尔Series mask = df['question'].apply(lambda row: all(word in row for word in substrings)) # 筛选行 filtered_df = df[mask]
方法2:多条件逻辑与(性能更优)
对每个子串用str.contains生成布尔Series,再用逻辑与(&)叠加所有条件:
substrings = ['King', 'England'] mask = True for word in substrings: # 逐次叠加条件,每个子串都必须存在 mask &= df['question'].str.contains(word) filtered_df = df[mask]
也可以用functools.reduce简化循环:
from functools import reduce import operator substrings = ['King', 'England'] mask = reduce(operator.and_, [df['question'].str.contains(word) for word in substrings]) filtered_df = df[mask]
方法3:正则正向预查(简洁写法)
将子串拼成包含多个正向肯定预查的正则表达式,一次性匹配所有子串:
substrings = ['King', 'England'] # 构造正则:(?=.*King)(?=.*England) regex_pattern = ''.join([f'(?=.*{word})' for word in substrings]) mask = df['question'].str.match(regex_pattern) filtered_df = df[mask]
额外说明
如果需要忽略大小写匹配,只需给str.contains或str.match添加case=False参数即可,比如:
df['question'].str.contains(word, case=False)
内容的提问来源于stack exchange,提问作者Gabriel Chan
相关产品推荐
相关产品推荐

