如何使用pandas筛选字符串列包含所有指定关键词(顺序不限不区分大小写)的行
pandas 多单词无序不区分大小写匹配筛选实现
示例数据
import pandas as pd import re BabyDataSet = [ ('Bob and martin and Andrew', 968), ('Jessica and julia and anthony', 155), ('Mary and john', 77), ('John', 578), ('Mel and diana', 973), ('martin bob diana and Andrew', 968) ] a = pd.DataFrame(data=BabyDataSet, columns=['Names', 'Births'])
需求为筛选Names列包含查询字符串martin andrew bob中所有单词的行,匹配不区分大小写、不要求单词顺序。
方案1:正则正向预查(推荐,性能更高)
利用正则的正向肯定预查特性,无需循环叠加掩码即可完成筛选:
query_str = "martin andrew bob" # 构造匹配所有单词的正则模式 pattern = r'(?i)' + ''.join([rf'(?=.*\b{re.escape(word)}\b)' for word in query_str.split()]) # 执行筛选 result = a[a['Names'].str.contains(pattern, regex=True)]
说明:
(?i)是正则内置标志,表示匹配过程不区分大小写(?=.*\b{word}\b)为正向肯定预查,要求字符串中必须存在完整的目标单词;\b是单词边界,避免误匹配包含目标单词的更长单词(如不会把bobby识别为匹配bob)re.escape会自动转义单词中包含的正则特殊字符,避免语法报错
方案2:apply+all(更直观易懂)
如果对正则不熟悉,可使用apply配合all函数实现,逻辑更直白:
query_str = "martin andrew bob" # 拆分查询词统一转小写 query_words = [word.lower() for word in query_str.split()] # 逐行判断是否包含所有查询词 result = a[a['Names'].apply(lambda x: all(word in x.lower() for word in query_words))]
说明:
该方案逻辑清晰,适合小数据集使用,大数据集下性能略低于正则方案。
两种方案筛选结果一致,输出如下:
Names Births 0 Bob and martin and Andrew 968 5 martin bob diana and Andrew 968
内容的提问来源于stack exchange,提问作者JFerro
相关产品推荐
相关产品推荐

