不同Dataframe的模糊匹配列
Fuzzy Match columns of Different Dataframe
背景
我有 2 个数据框,它们没有可以合并到的公共键。两个 df 都有一个包含 "entity name" 的列。一个 df 包含 8000 多个实体,另一个包含近 2000 个实体。
示例数据:
vendor_df=
Name of Vendor City State ZIP
FREDDIE LEES AMERICAN GOURMET SAUCE St. Louis MO 63101
CITYARCHRIVER 2015 FOUNDATION St. Louis MO 63102
GLAXOSMITHKLINE CONSUMER HEALTHCARE St. Louis MO 63102
LACKEY SHEET METAL St. Louis MO 63102
regulator_df =
Name of Entity Committies
LACKEY SHEET METAL Private
PRIMUS STERILIZER COMPANY LLC Private
HELGET GAS PRODUCTS INC Autonomous
ORTHOQUEST LLC Governmant
问题所在:
我必须模糊匹配这两列(Name of vendor
& Name of Entity
)的实体并得到一个分数。因此,需要知道数据帧 1(vendor_df
) 的第一个值是否与数据帧 2(regulator_df).[=16= 的 2000 个实体中的任何一个相匹配]
我检查的 Whosebug 链接:
fuzzy match between 2 columns (Python)
代码
import pandas as pd
from fuzzywuzzy import fuzz
from fuzzywuzzy import process
vendor_df = pd.read_excel('C:\Users\40101584\Desktop\AUS CUB AML\Vendors_Sheet.xlsx', sheet_name=0)
regulator_df = pd.read_excel('C:\Users\40101584\Desktop\AUS CUB AML\Regulated_Vendors_Sheet.xlsx', sheet_name=0)
compare = pd.MultiIndex.from_product([vendor_df['Name of vendor'],
regulator_df['Name of Entity']]).to_series()
def metrics(tup):
return pd.Series([fuzz.ratio(*tup),
fuzz.token_sort_ratio(*tup)],
['ratio', 'token'])
#compare.apply(metrics) -- Either this works or the below line
result = compare.apply(metrics).unstack().idxmax().unstack(0)
上述代码有问题:
如果两个数据帧很小,代码就可以工作,但是当我给出完整的数据集时,它会永远花费。以上代码取自第 3 link.
如果同样的事情可以快速运行或可以处理大型数据集,有什么解决方案吗?
更新 1
如果我们通过或硬编码分数 80 将过滤 series/dataframe 只有 fuzzyscore > 80 ?[=16,上面的代码可以更快吗? =]
下面的解决方案比我发布的更快,但如果有人有更快的方法请告诉:
matched_vendors = []
for row in vendor_df.index:
vendor_name = vendor_df.get_value(row,"Name of vendor")
for columns in regulator_df.index:
regulated_vendor_name=regulator_df.get_value(columns,"Name of Entity")
matched_token=fuzz.partial_ratio(vendor_name,regulated_vendor_name)
if matched_token> 80:
matched_vendors.append([vendor_name,regulated_vendor_name,matched_token])
在我的例子中,我也只需要寻找 80 以上的值。我根据我的用途修改了你的代码 case.hope 它有帮助。
compare = compare.apply(metrics)
compare_80=compare[(compare['ratio'] >80) & (compare['token'] >80)]
我已经使用并行处理实现了 Python 中的代码,这将比串行计算快得多。此外,在模糊度量分数超过阈值的情况下,只有那些计算是并行执行的。代码见下方link:
Vesrion 兼容性:
pandas version :: 1.1.5 ,
numpy vesrion:: 1.19.5,
fuzzywuzzy version :: 1.1.0 ,
joblib version :: 0.18.0
Fuzzywuzzy 指标说明:
代码输出:
背景
我有 2 个数据框,它们没有可以合并到的公共键。两个 df 都有一个包含 "entity name" 的列。一个 df 包含 8000 多个实体,另一个包含近 2000 个实体。
示例数据:
vendor_df=
Name of Vendor City State ZIP
FREDDIE LEES AMERICAN GOURMET SAUCE St. Louis MO 63101
CITYARCHRIVER 2015 FOUNDATION St. Louis MO 63102
GLAXOSMITHKLINE CONSUMER HEALTHCARE St. Louis MO 63102
LACKEY SHEET METAL St. Louis MO 63102
regulator_df =
Name of Entity Committies
LACKEY SHEET METAL Private
PRIMUS STERILIZER COMPANY LLC Private
HELGET GAS PRODUCTS INC Autonomous
ORTHOQUEST LLC Governmant
问题所在:
我必须模糊匹配这两列(Name of vendor
& Name of Entity
)的实体并得到一个分数。因此,需要知道数据帧 1(vendor_df
) 的第一个值是否与数据帧 2(regulator_df).[=16= 的 2000 个实体中的任何一个相匹配]
我检查的 Whosebug 链接:
fuzzy match between 2 columns (Python)
代码
import pandas as pd
from fuzzywuzzy import fuzz
from fuzzywuzzy import process
vendor_df = pd.read_excel('C:\Users\40101584\Desktop\AUS CUB AML\Vendors_Sheet.xlsx', sheet_name=0)
regulator_df = pd.read_excel('C:\Users\40101584\Desktop\AUS CUB AML\Regulated_Vendors_Sheet.xlsx', sheet_name=0)
compare = pd.MultiIndex.from_product([vendor_df['Name of vendor'],
regulator_df['Name of Entity']]).to_series()
def metrics(tup):
return pd.Series([fuzz.ratio(*tup),
fuzz.token_sort_ratio(*tup)],
['ratio', 'token'])
#compare.apply(metrics) -- Either this works or the below line
result = compare.apply(metrics).unstack().idxmax().unstack(0)
上述代码有问题:
如果两个数据帧很小,代码就可以工作,但是当我给出完整的数据集时,它会永远花费。以上代码取自第 3 link.
如果同样的事情可以快速运行或可以处理大型数据集,有什么解决方案吗?
更新 1
如果我们通过或硬编码分数 80 将过滤 series/dataframe 只有 fuzzyscore > 80 ?[=16,上面的代码可以更快吗? =]
下面的解决方案比我发布的更快,但如果有人有更快的方法请告诉:
matched_vendors = []
for row in vendor_df.index:
vendor_name = vendor_df.get_value(row,"Name of vendor")
for columns in regulator_df.index:
regulated_vendor_name=regulator_df.get_value(columns,"Name of Entity")
matched_token=fuzz.partial_ratio(vendor_name,regulated_vendor_name)
if matched_token> 80:
matched_vendors.append([vendor_name,regulated_vendor_name,matched_token])
在我的例子中,我也只需要寻找 80 以上的值。我根据我的用途修改了你的代码 case.hope 它有帮助。
compare = compare.apply(metrics)
compare_80=compare[(compare['ratio'] >80) & (compare['token'] >80)]
我已经使用并行处理实现了 Python 中的代码,这将比串行计算快得多。此外,在模糊度量分数超过阈值的情况下,只有那些计算是并行执行的。代码见下方link:
Vesrion 兼容性:
pandas version :: 1.1.5 ,
numpy vesrion:: 1.19.5,
fuzzywuzzy version :: 1.1.0 ,
joblib version :: 0.18.0
Fuzzywuzzy 指标说明:
代码输出: