gin*_*ard 2 python string-matching python-2.7 pandas fuzzywuzzy
我有以下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"
Run Code Online (Sandbox Code Playgroud)
我还有以下数据框(我也以字典形式保存),它有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"
Run Code Online (Sandbox Code Playgroud)
我想要做的是将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"
Run Code Online (Sandbox Code Playgroud)
我已经完成了确定完全匹配的联接.保留索引并不重要,因为每个df中的产品ID都是唯一的.结果也可以保存到新的数据帧中,然后将其应用于具有大约1400万行的第三个数据帧.
我使用了以下问题和答案(以及其他):
有可能做模糊匹配与python pandas
模糊合并匹配与重复包括尝试水母模块建议在其中一个答案
Python模糊匹配fuzzywuzzy保持只有最佳匹配
模糊匹配项列在一列
以及各种循环/功能/映射等,但没有成功,要么获得具有低分数的第一个"模糊匹配",要么没有检测到匹配.
我喜欢在这里生成匹配/距离分数列的想法,因为它可以让我加快手动检查过程.
我正在使用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
Run Code Online (Sandbox Code Playgroud)
设置可接受距离的阈值.我设置50
查找df2
每行具有最大值的索引值(for ).
threshold = df3.max(1) > 50
idxmax = df3.idxmax(1)
Run Code Online (Sandbox Code Playgroud)
做作业
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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1732 次 |
最近记录: |