我有2个大型数据集,我已将它们读入Pandas DataFrames(分别为〜20K行和〜40K行)。当我尝试在地址字段上使用pandas.merge完全合并这两个DF时,与行数相比,我得到的匹配数很少。所以我想我会尝试模糊字符串匹配,以查看它是否可以改善输出匹配的数量。

为此,我尝试在DF1中创建一个新列(20K行),这是在DF1 [addressline]到DF2 [addressline]上应用Fuzzywuzzy extractone函数的结果。我很快意识到这将是永远的,因为它将进行近10亿次比较。

这两个数据集都具有“县”字段,我的问题是:是否有办法基于“县”字段相同,有条件地在两个DF中的“地址线”字段上进行模糊字符串匹配?在研究类似于我的问题时,我偶然发现了这个讨论:Fuzzy logic on big datasets using Python

但是,我仍然对如何基于县进行分组/阻止字段感到困惑(没有双关语)。任何建议将不胜感激!

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用作变量,并在进行模糊搜索之前使用它来对您的选择进行子集化(请注意,这需要在整个数据框中而不是仅在address列上应用该函数)

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)

10-04 16:27
查看更多