簡體   English   中英

如何模糊匹配Python中的兩個列表

[英]How to fuzzy match two lists in Python

我有兩個列表: ref_listinp_list 如何利用 FuzzyWuzzy 從參考列表中匹配輸入列表?

inp_list = pd.DataFrame(['ADAMS SEBASTIAN',  'HAIMBILI SEUN',  'MUTESI 
                          JOHN', 'SHEETEKELA MATT', 'MUTESI JOHN KUTALIKA', 
                          'ADAMS SEBASTIAN HAUSIKU', 'PETERS WILSON', 
                          'PETERS MARIO', 'SHEETEKELA  MATT NICKY'],
                          columns =['Names'])



ref_list = pd.DataFrame(['ADAMS SEBASTIAN HAUSIKU', 'HAIMBILI MIKE', 'HAIMBILI SEUN', 'MUTESI JOHN 
                         KUTALIKA', 'PETERS WILSON MARIO', 'SHEETEKELA  MATT NICKY MBILI'], columns = 
                        ['Names']) 

經過一些研究,我修改了一些我在 inte.net 上找到的代碼。 這些代碼的問題 - 它們在小樣本量上工作得很好。 在我的例子中, inp_listref_list的長度分別為 29k 和 18k,運行需要一天多的時間。

下面是代碼,首先定義了一個 helper function。

def match_term(term, inp_list, min_score=0):
    # -1 score in case I don't get any matches
    max_score = -1
    
    # return empty for no match 
    max_name = ''
    
    # iterate over all names in the other
    for term2 in inp_list:
        # find the fuzzy match score
        score = fuzz.token_sort_ratio(term, term2)
    
        # checking if I am above my threshold and have a better score
        if (score > min_score) & (score > max_score):
            max_name = term2
            max_score = score
    return (max_name, max_score)


# list for dicts for easy dataframe creation
dict_list = []

#iterating over the sales file
for name in inp_list:
    #use the defined function above to find the best match, also set the threshold to a chosen #
    match = match_term(name, ref_list, 94)
    
    #new dict for storing data
    dict_ = {}
    dict_.update({'passenger_name': name})
    dict_.update({'match_name': match[0]})
    dict_.update({'score': match[1]})
    
    dict_list.append(dict_)

這些代碼在哪里可以改進以順利運行並可能避免評估已經評估的項目?

您可以嘗試對操作進行矢量化,而不是在循環中評估分數。

制作一個df ,其中第一個 col refref_list ,第二個 col inp_listinp中的每個名稱。 然后調用df.apply(lambda row:process.extractOne(row['inp'], row['ref']), axis=1) 最后,您將在ref_list中為inp_list中的每個名稱獲得最佳匹配名稱和得分。

您使用的措施在計算上要求很高,並且有許多對字符串。 fuzzywuzzy ,您還可以嘗試使用名為string-grouper grouper 的庫,它利用更快的 Tf-idf 方法和余弦相似度度量來查找相似詞。 舉個例子:

import random, string, time
import pandas as pd
from string_grouper import match_strings

alphabet = list(string.ascii_lowercase)
from_r, to_r = 0, len(alphabet)-1

random_strings_1 = ["".join(alphabet[random.randint(from_r, to_r)]
                            for i in range(6)) for j in range(5000)]
random_strings_2 = ["".join(alphabet[random.randint(from_r, to_r)]
                            for i in range(6)) for j in range(5000)]
                
series_1 = pd.Series(random_strings_1)
series_2 = pd.Series(random_strings_2)

t_1 = time.time()
matches = match_strings(series_1, series_2,
                        min_similarity=0.6)
t_2 = time.time()
print(t_2 - t_1)
print(matches)

進行 25.000.000 次比較只需要不到一秒鍾的時間:要對庫進行更有用的測試,請看這里: https://bergvca.github.io/2017/10/14/super-fast-string-matching.html據稱

“使用這種方法可以僅使用雙核筆記本電腦在 42 分鍾內搜索一組 663,000 個公司名稱中的近似重復項”。

要進一步調整您的匹配算法,請查看**kwargs arguments ,您可以將其提供給上面的match_strings function。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM