pandas 如何在fuzzywuzzy中避免循环匹配

f5emj3cl  于 2023-05-27  发布在  其他
关注(0)|答案(1)|浏览(158)

下面是我的dataframe:

df = pd.DataFrame(
    dict(Name=['Emma Howard', 'Emma Ward', 'Emma Warner', 'Emma Wayden'],
         Age=[33, 34, 43, 44], Score=[90, 95, 93, 92])
)

list2 = df['Name'].tolist()

我正在应用fuzzywuzzy过程:

process.extractBests(i, list2, score_cutoff=80, scorer=fuzz.ratio)

提取列Name上的最佳匹配,结果如下所示:

我期望的输出是:

逻辑是“Emma霍华德”和“Emma Ward”已经在第一行匹配,因此我不想在第二行显示“Emma Howard”匹配,第三和第四行也是如此。
以下是完整的伪代码

mat1 = []
list1 = df['Name'].tolist()
list2 = df['Name'].tolist()
list3 = df['Name'].tolist()

for i in list1:
    list2 = [x for x in list2 if x != i]
    mat1.append(process.extractBests(i, list2, score_cutoff=80, scorer=fuzz.ratio))
    list2 = list3
df['matches'] = mat1
df.to_csv("xyz.csv")
z31licg0

z31licg01#

IIUC,一旦使用了一个名称,它就不再可用于后续行,因此您可以使用set操作来删除已经分配的名称:

uniques = set(df['Name'])
matches = {}
for idx, row in df.iterrows():
    uniques -= set([row.Name])  # remove current name
    res = process.extractBests(row.Name, uniques, score_cutoff=80)
    uniques -= set([name for name, score in res])  # remove best results
    matches[idx] = res
df['matches'] = pd.Series(matches)

注意:在每次迭代中,由于集合中的行数较少,因此比较速度更快。

输出:

>>> df
          Name  Age  Score                                 matches
0  Emma Howard   33     90                       [(Emma Ward, 90)]
1    Emma Ward   34     95  [(Emma Wayden, 80), (Emma Warner, 80)]
2  Emma Warner   43     93                                      []
3  Emma Wayden   44     92                                      []

相关问题