基于条件的 2 个大型数据集的模糊模糊字符串匹配 - python
Fuzzy Wuzzy String Matching on 2 Large Data Sets Based on a Condition - python
我有 2 个大型数据集,我已读入 Pandas DataFrames(分别约 20K 行和 ~40K 行)。当我尝试在地址字段上使用 pandas.merge 完全合并这两个 DF 时,与行数相比,我得到的匹配数量微不足道。所以我想我会尝试模糊字符串匹配,看看它是否提高了输出匹配的数量。
我通过尝试在 DF1(20K 行)中创建一个新列来解决这个问题,这是在 DF1[addressline] 到 DF2[addressline] 上应用 fuzzywuzzy extractone 函数的结果。我很快意识到这将花费很长时间,因为它将进行近 10 亿次比较。
这两个数据集都有 "County" 字段,我的问题是:有没有办法根据 [=29] 有条件地对两个 DF 中的 "addressline" 字段进行模糊字符串匹配=] 字段相同?在研究与我类似的问题时,我偶然发现了这个讨论:Fuzzy logic on big datasets using Python
然而,我仍然不清楚(没有双关语意)如何处理基于县的 grouping/blocking 字段。任何建议将不胜感激!
import pandas as pd
from fuzzywuzzy import process
def fuzzy_match(x, choices, scorer, cutoff):
return process.extractOne(x, choices = choices, scorer = scorer, score_cutoff= cutoff)[0]
test = pd.DataFrame({'Address1':['123 Cheese Way','234 Cookie Place','345 Pizza Drive','456 Pretzel Junction'],'ID':['X','U','X','Y']})
test2 = pd.DataFrame({'Address1':['123 chese wy','234 kookie Pl','345 Pizzza DR','456 Pretzel Junktion'],'ID':['X','U','X','Y']})
test['Address1'] = test['Address1'].apply(lambda x: x.lower())
test2['Address1'] = test2['Address1'].apply(lambda x: x.lower())
test['FuzzyAddress1'] = test['Address1'].apply(fuzzy_match, args = (test2['Address1'], fuzz.ratio, 80))
我添加了 2 个图像,它们是导入 Excel 的 2 个不同 DF 的样本集。并未包含所有字段,因为它们对我的问题并不重要。为了重申我的最终目标,我希望在其中一个 DF 中有一个新列,该列具有通过模糊匹配地址行与第二个 DF 中的其他地址行的最佳结果,但仅适用于县在两个 DF 之间匹配的那些行。从那里我计划合并两个 df,一个在模糊匹配地址和第二个 DF 中的地址行列。希望这听起来不会令人困惑。
您可以调整 fuzzy_match
函数以将 id 作为变量,并在进行模糊搜索之前使用它来对您的选择进行子集化(请注意,这需要在整个数据帧上应用该函数,而不仅仅是地址列)
def fuzzy_match(x, choices, scorer, cutoff):
match = process.extractOne(x['Address1'],
choices=choices.loc[choices['ID'] == x['ID'],
'Address1'],
scorer=scorer,
score_cutoff=cutoff)
if match:
return match[0]
test['FuzzyAddress1'] = test.apply(fuzzy_match,
args=(test2, fuzz.ratio, 80),
axis=1)
我有 2 个大型数据集,我已读入 Pandas DataFrames(分别约 20K 行和 ~40K 行)。当我尝试在地址字段上使用 pandas.merge 完全合并这两个 DF 时,与行数相比,我得到的匹配数量微不足道。所以我想我会尝试模糊字符串匹配,看看它是否提高了输出匹配的数量。
我通过尝试在 DF1(20K 行)中创建一个新列来解决这个问题,这是在 DF1[addressline] 到 DF2[addressline] 上应用 fuzzywuzzy extractone 函数的结果。我很快意识到这将花费很长时间,因为它将进行近 10 亿次比较。
这两个数据集都有 "County" 字段,我的问题是:有没有办法根据 [=29] 有条件地对两个 DF 中的 "addressline" 字段进行模糊字符串匹配=] 字段相同?在研究与我类似的问题时,我偶然发现了这个讨论:Fuzzy logic on big datasets using Python
然而,我仍然不清楚(没有双关语意)如何处理基于县的 grouping/blocking 字段。任何建议将不胜感激!
import pandas as pd
from fuzzywuzzy import process
def fuzzy_match(x, choices, scorer, cutoff):
return process.extractOne(x, choices = choices, scorer = scorer, score_cutoff= cutoff)[0]
test = pd.DataFrame({'Address1':['123 Cheese Way','234 Cookie Place','345 Pizza Drive','456 Pretzel Junction'],'ID':['X','U','X','Y']})
test2 = pd.DataFrame({'Address1':['123 chese wy','234 kookie Pl','345 Pizzza DR','456 Pretzel Junktion'],'ID':['X','U','X','Y']})
test['Address1'] = test['Address1'].apply(lambda x: x.lower())
test2['Address1'] = test2['Address1'].apply(lambda x: x.lower())
test['FuzzyAddress1'] = test['Address1'].apply(fuzzy_match, args = (test2['Address1'], fuzz.ratio, 80))
我添加了 2 个图像,它们是导入 Excel 的 2 个不同 DF 的样本集。并未包含所有字段,因为它们对我的问题并不重要。为了重申我的最终目标,我希望在其中一个 DF 中有一个新列,该列具有通过模糊匹配地址行与第二个 DF 中的其他地址行的最佳结果,但仅适用于县在两个 DF 之间匹配的那些行。从那里我计划合并两个 df,一个在模糊匹配地址和第二个 DF 中的地址行列。希望这听起来不会令人困惑。
您可以调整 fuzzy_match
函数以将 id 作为变量,并在进行模糊搜索之前使用它来对您的选择进行子集化(请注意,这需要在整个数据帧上应用该函数,而不仅仅是地址列)
def fuzzy_match(x, choices, scorer, cutoff):
match = process.extractOne(x['Address1'],
choices=choices.loc[choices['ID'] == x['ID'],
'Address1'],
scorer=scorer,
score_cutoff=cutoff)
if match:
return match[0]
test['FuzzyAddress1'] = test.apply(fuzzy_match,
args=(test2, fuzz.ratio, 80),
axis=1)