首页 文章

在一个Python数据帧/字典中搜索另一个数据帧中的模糊匹配

提问于
浏览
2

我有以下pandas数据框,包含50,000个唯一行和20列(包含相关列的片段):

df1

PRODUCT_ID           PRODUCT_DESCRIPTION
0           165985858958         "Fish Burger with Lettuce"
1           185965653252         "Chicken Salad with Dressing"
2           165958565556         "Pork and Honey Rissoles"
3           655262522233         "Cheese, Ham and Tomato Sandwich"
4           857485966653         "Coleslaw with Yoghurt Dressing"
5           524156285551         "Lemon and Raspberry Cheesecake"

我还有以下数据框(我也以字典形式保存),它有2列和20,000个唯一行:

df2 (also saved as dict_2)

PROD_ID   PROD_DESCRIPTION
0      548576    "Fish Burger"
1      156956    "Chckn Salad w/Ranch Dressing"
2      257848    "Rissoles - Lamb & Rosemary"
3      298770    "Lemn C-cake"
4      651452    "Potato Salad with Bacon"
5      100256    "Cheese Cake - Lemon Raspberry Coulis"

我想要做的是将df1中的“PRODUCT_DESCRIPTION”字段与df2中的“PROD_DESCRIPTION”字段进行比较,找到最接近的匹配/匹配以帮助解除繁重的部分 . 然后我需要手动检查匹配但是会更快更好理想的结果看起来像这样,例如注意到一个或多个部分匹配:

PRODUCT_ID      PRODUCT_DESCRIPTION               PROD_ID   PROD_DESCRIPTION
0    165985858958    "Fish Burger with Lettuce"        548576    "Fish Burger"
1    185965653252    "Chicken Salad with Dressing"     156956    "Chckn Salad w/Ranch Dressing"
2    165958565556    "Pork and Honey Rissoles"         257848    "Rissoles - Lamb & Rosemary"     
3    655262522233    "Cheese, Ham and Tomato Sandwich" NaN       NaN
4    857485966653    "Coleslaw with Yoghurt Dressing"  NaN       NaN
5    524156285551    "Lemon and Raspberry Cheesecake"  298770    "Lemn C-cake"
6    524156285551    "Lemon and Raspberry Cheesecake"  100256    "Cheese Cake - Lemon Raspberry Coulis"

我已经完成了确定完全匹配的联接 . 保留索引并不重要,因为每个df中的产品ID都是唯一的 . 结果也可以保存到新的数据帧中,然后将其应用于具有大约1400万行的第三个数据帧 .

我使用了以下问题和答案(以及其他):

Is it possible to do fuzzy match merge with python pandas
Fuzzy merge match with duplicates包括尝试水母模块,如其中一个答案所示
Python fuzzy matching fuzzywuzzy keep only the best match
Fuzzy match items in a column of an array

以及各种循环/功能/映射等,但没有成功,要么获得具有低分数的第一个“模糊匹配”,要么没有检测到匹配 .

我喜欢根据here生成匹配/距离分数列的想法,因为它可以让我加快手动检查过程 .

我正在使用Python 2.7,pandas并安装了fuzzywuzzy .

2 回答

  • 0

    使用 fuzz.ratio 作为我的距离度量,像这样计算我的距离矩阵

    df3 = pd.DataFrame(index=df.index, columns=df2.index)
    
    for i in df3.index:
        for j in df3.columns:
            vi = df.get_value(i, 'PRODUCT_DESCRIPTION')
            vj = df2.get_value(j, 'PROD_DESCRIPTION')
            df3.set_value(
                i, j, fuzz.ratio(vi, vj))
    
    print(df3)
    
        0   1   2   3   4   5
    0  63  15  24  23  34  27
    1  26  84  19  21  52  32
    2  18  31  33  12  35  34
    3  10  31  35  10  41  42
    4  29  52  32  10  42  12
    5  15  28  21  49   8  55
    

    设置可接受距离的阈值 . 我设置 50
    找到每行具有最大值的索引值(对于 df2 ) .

    threshold = df3.max(1) > 50
    idxmax = df3.idxmax(1)
    

    做作业

    df['PROD_ID'] = np.where(threshold, df2.loc[idxmax, 'PROD_ID'].values, np.nan)
    df['PROD_DESCRIPTION'] = np.where(threshold, df2.loc[idxmax, 'PROD_DESCRIPTION'].values, np.nan)
    df
    

    enter image description here

  • 5

    您应该能够遍历两个数据帧并使用所需信息填充第3个数据帧的dict:

    d = {
        'df1_id': [],
        'df1_prod_desc': [],
        'df2_id': [],
        'df2_prod_desc': [],
        'fuzzywuzzy_sim': []
    }
    for _, df1_row in df1.iterrows():
        for _, df2_row in df2.iterrows():
            d['df1_id'] = df1_row['PRODUCT_ID']
            ...
    df3 = pd.DataFrame.from_dict(d)
    

相关问题