我在数据框中有一个名为“文本”的列,其中写了很多东西。我正在尝试验证此列中是否有模式列表中的任何字符串(例如pattern1,pattern2,pattern3)。我希望创建另一个布尔列,说明是否找到了这些模式中的任何一个。
但是,重要的是在几乎没有错误问题时匹配模式。例如,如果在模式列表中我有“ mickey”和“ mouse”,我也希望它也与“ m0use”和“ muckey”匹配,而不仅仅是完整的正确模式字符串。
我尝试过使用正则表达式库:
import regex
list_of_patterns = ['pattern1','pattern2','pattern3','pattern4']
df['contains_any_pattern'] = df['text'].apply(lambda x: regex.search(pattern=('^(' + '|'.join(list_of_patterns) + ').${e<=2:[a-zA-Z]}'),string=x,flags=re.IGNORECASE))
我之后检查了文本,并确定这是行不通的。有谁有更好的主意来解决这个问题?
这里是一个简短的例子:
df = pd.DataFrame({'id':[1,2,3,4,5],
'text':['my name is mickey mouse',
'my name is donkey kong',
'my name is mockey',
'my surname is m0use',
'hey, its me, mario!'
]})
list_of_patterns = ['mickey','mouse']
df['contains_pattern'] = df['text'].apply(lambda x: regex.search(pattern=r'(?i)^('+ '|'.join(list_of_patterns) +'){s<=2:[a-zA-Z]}',string=x))
这是生成的df:
id text contains_pattern
1 my name is mickey mouse None
2 my name is donkey kong None
3 my name is mockey None
4 my surname is m0use None
5 hey,its me, mario None
您可以使用类似方法修复代码
df['contains_any_pattern'] = df['text'].apply(lambda x: regex.search(r'(?i)\b(?:' + '|'.join(list_of_patterns) + r'){e<=2}\b', x))
或者,如果搜索词可能包含特殊字符,请使用
pat = r'(?i)(?<!\w)(?:' + '|'.join([re.escape(p) for p in list_of_patterns]) + r'){e<=2}(?!\w)'
df['contains_any_pattern'] = df['text'].apply(lambda x: regex.search(pat, x))
模式现在看起来像(?i)\b(?:mouse|mickey){e<=2}\b
。进行调整以适应您的需要,但确保量词在组的后面。
re.IGNORECASE
来自re
包,您可以简单地使用内联修饰符(?i)
启用与当前regex
库不区分大小写的匹配。
如果需要处理成百上千个搜索词,则可以利用Speed up millions of regex replacements in Python 3中描述的方法。