我有以下 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(也保存为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。
最佳答案
使用 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
关于python - 在一个 Python 数据帧/字典中搜索另一个数据帧中的模糊匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41455093/