Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 百万行上的模糊正则表达式匹配_Python_Regex_Pandas_Multiprocessing_Fuzzy - Fatal编程技术网

Python 百万行上的模糊正则表达式匹配

Python 百万行上的模糊正则表达式匹配,python,regex,pandas,multiprocessing,fuzzy,Python,Regex,Pandas,Multiprocessing,Fuzzy,我试图检查字符串列和引用列表之间的模糊匹配。字符串系列包含超过1m行,参考列表包含超过10k个条目 例如: df['NAMES'] = pd.Series(['ALEXANDERS', 'NOVA XANDER', 'SALA MANDER', 'PARIS HILTON', 'THE HARIS DOWNTOWN', 'APARISIAN', 'PARIS', 'MARIN XO']) # 1mil rows ref_df['REF_NAMES'] = pd.Series(['XANDER'

我试图检查字符串列和引用列表之间的模糊匹配。字符串系列包含超过1m行,参考列表包含超过10k个条目

例如:

df['NAMES'] = pd.Series(['ALEXANDERS', 'NOVA XANDER', 'SALA MANDER', 'PARIS HILTON', 'THE HARIS DOWNTOWN', 'APARISIAN', 'PARIS', 'MARIN XO']) # 1mil rows

ref_df['REF_NAMES'] = pd.Series(['XANDER','PARIS']) #10 k rows

###Output should look like 

df['MATCH'] = pd.Series([Nan, 'XANDER', 'MANDER', 'PARIS', 'HARIS', Nan, 'PARIS', Nan])
如果单词单独出现在字符串中(并且在该字符串中,最多允许1个字符替换),则应生成匹配

例如,“巴黎”可以与“巴黎希尔顿”、“哈里斯市中心”相匹敌,但不能与“亚帕里斯人”相匹敌

类似地,“XANDER”与“NOVAXANDER”和“SALAMANDER”匹配(MANDER与XANDER相差1个字符),但不与“ALEXANDERS”匹配

到目前为止,我们已经编写了相同的逻辑(如下所示),尽管比赛需要4个多小时。。需要把时间限制在30分钟以内

现行代码-

tags_regex = ref_df['REF_NAMES'].tolist()
tags_ptn_regex = '|'.join([f'\s+{tag}\s+|^{tag}\s+|\s+{tag}$' for tag in tags_regex])


def search_it(partyname):
    m = regex.search("("+tags_ptn_regex+ ")"+"{s<=1:[A-Z]}",partyname):
    if m is not None:
        return m.group()
    else:
        return None
    
df['MATCH'] = df['NAMES'].str.apply(search_it)
tags\u regex=ref\u df['ref\u NAMES'].tolist()
tags_ptn_regex='|'。连接([f'\s+{tag}\s+| ^{tag}\s+|\s+{tag}$'用于tags_regex中的tag])
def search_it(partyname):

m=regex.search(“(“+tags_ptn_regex+”)”+“{s您的模式效率很低,因为您在regex中重复了三次
tag
模式。您只需要创建一个带有所谓空白边界的模式,
(?和
(?!\s)
,并且只需要一个
tag
模式

接下来,如果您有数千个备选方案,那么即使是单个
标记
模式regex也会非常慢,因为可能会出现这样的备选方案,这些备选方案在字符串中的同一位置匹配,因此会有太多回溯

要减少这种回溯,您将需要一个

以下是一个工作片段:

导入正则表达式
作为pd进口熊猫
##类来构建正则表达式trie,请参见https://stackoverflow.com/a/42789508/3832970
类Trie():
“”“Python中的Regex::Trie。从单词列表中创建Trie。Trie可以导出为Regex模式。
相应的正则表达式应该比简单的正则表达式联合快得多
定义初始化(自):
self.data={}
def添加(自我,word):
ref=自我数据
对于word中的字符:
ref[char]=ref中的char和ref[char]或{}
ref=ref[char]
参考['']=1
def转储(自):
返回self.data
def quote(自我,字符):
return regex.escape(char)
定义模式(自身、pData):
数据=pData
如果数据中的“”和len(data.keys())==1:
一无所获
alt=[]
cc=[]
q=0
对于排序后的字符(data.keys()):
如果存在(数据[char],dict):
尝试:
recurse=self.\u模式(数据[char])
alt.append(self.quote(char)+递归)
除:
cc.append(self.quote(char))
其他:
q=1
cOnly=非len(alt)>0
如果len(cc)>0:
如果len(cc)==1:
alt.append(抄送[0])
其他:
alt.append('['+'.join(cc)+']'))
如果len(alt)==1:
结果=alt[0]
其他:
结果=“(?:“+”|“.join(alt)+”)
如果q:
如果仅限于:
结果+=“?”
其他:
result=“(?:%s)?%result
返回结果
def模式(自):
返回self.\u模式(self.dump())
##主代码的开始
df=pd.DataFrame()
df['NAMES']=pd.系列(['ALEXANDERS'、'NOVA XANDER'、'SALA MANDER'、'PARIS HILTON'、'THE HARIS DOWNTOWN'、'APARISIAN'、'PARIS'、'MARIN XO')#百万行
ref_df=pd.DataFrame()
ref_df['ref_NAMES']=pd.系列(['XANDER','PARIS'])#10 k行
trie=trie()
对于ref_df['ref_NAMES']中的单词。tolist():
添加(word)

tags_ptn_regex=regex.compile(r)(?:(“NOVA XNDER”怎么样?“XANDER”匹配吗?是的,最多允许1次替换、删除或添加。谢谢!首先你可以简化你的regexp:
\s+{tag}\s+^{tag}\s+\s+{tag tag}$
等同于
\b{tag b}\code>其中
\b
是单词边界。2)为什么要在成功后第二次运行regex.search?虽然我认为这两个改进的效果都相对较小2)我认为你的regex根本不起作用-在“ALEXANDER”上试用过,它匹配。因此,首先,你在正确性方面存在问题。我认为你不可能轻松地进行“最多1次替换、删除或添加”使用regex很容易。到目前为止,它最多可以进行1次替换。添加/删除是一个很好的选择。我只编辑了一次脚本以便使用regex.search,…正如你所说…没有太多改进想法谢谢Wiktor,,这对v帮助很大!!令人印象深刻。我曾考虑过建议构建一个有限自动机,但后来决定它太复杂了,而且无论如何都不会有效率。这是一个很好的方法。我想知道它在这个特定数据上的速度有多快。@YaroslavFyodorov当然,模糊量词会减慢速度,但这种方法本身被证明可以很好地处理多达50K个不同长度的搜索短语。