基于条件python的{2}大数据集的模糊Wuzzy字符串匹配

时间:2017-03-17 00:58:43

标签: python pandas fuzzy-comparison fuzzywuzzy large-data

我有2个大型数据集,我已经读入Pandas DataFrames(分别为~20K行和~40K行)。当我尝试在地址字段上使用pandas.merge直接合并这两个DF时,与行数相比,我获得了微不足道的匹配数。所以我想我会尝试模糊字符串匹配,看它是否能改善输出匹配的数量。

我试图在DF1(20K行)中创建一个新列,这是将DF1 [地址线]上的fuzzywuzzy extractone函数应用于DF2 [addressline]的结果。我很快意识到这将需要永远,因为它将进行近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之间匹配的那些行。从那里我计划合并两个dfs,一个在模糊匹配地址和第二个DF中的地址行列。希望这听起来并不令人困惑。

  

1 个答案:

答案 0 :(得分:5)

您可以调整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)