Python 如何在近似字符串上合并?
我想将大约国家/地区名称上的2个数据框合并到,但我得到以下错误: TypeError:“非类型”对象不可调用 请参见下面的说明性代码:Python 如何在近似字符串上合并?,python,pandas,Python,Pandas,我想将大约国家/地区名称上的2个数据框合并到,但我得到以下错误: TypeError:“非类型”对象不可调用 请参见下面的说明性代码: cl = {'Country' : ["Brazil", "US", "Russia"], 'BL?':['No', 'No','Yes']} clist = pd.DataFrame.from_dict(cl) cd = {'Country' : ["Braizl", "us", "Rusia"]} cdata = pd.DataFrame.from_d
cl = {'Country' : ["Brazil", "US", "Russia"], 'BL?':['No', 'No','Yes']}
clist = pd.DataFrame.from_dict(cl)
cd = {'Country' : ["Braizl", "us", "Rusia"]}
cdata = pd.DataFrame.from_dict(cd)
clist = clist.sort_values('Country')
cdata = cdata.sort_values('Country')
cdata = pd.merge_asof(cdata,clist,on='Country')
预期结果将合并两个dfs,cdata df的“BL”列将包含YES/NO值
提前谢谢你 根据你的例子,我找到了一个解决方案。这不是很像蟒蛇,但很管用!(假设您在
clist
中为每个cdata
错售国家/地区提供了匹配的国家/地区名称)
我正在使用库来计算levenshtein距离。
您可以使用pip安装它:
pip install editdistance
这应该会让你接近,但它不会100%准确。你可以用<代码>模糊模糊模糊使用Levenshtein距离计算两个字符串之间的差值:
from fuzzywuzzy import process
# create a choice list
choices = clist['Country'].values.tolist()
# apply fuzzywuzzy to each row using lambda expression
cdata['Close Country'] = cdata['Country'].apply(lambda x: process.extractOne(x, choices)[0])
# merge
cdata.merge(clist, left_on='Close Country', right_on='Country')
Country_x Close Country Country_y BL?
0 Braizl Brazil Brazil No
1 Rusia Russia Russia Yes
2 us US US No
您甚至可以返回匹配百分比,如果只想保持匹配值大于85%,则只需保持值>n
添加匹配百分比
可以在合并之前执行布尔索引,以删除不匹配项,然后进行合并:
cdata[['Close Country', 'Percent Match']] = cdata['Close Country'].apply(pd.Series)
cdata = cdata[cdata['Percent Match']>85]
也可以在合并后执行此操作:
merge = cdata.merge(clist, left_on='Close Country', right_on='Country')
merge[merge['Percent Match'] > 85]
fuzzyfuzzy
返回匹配百分比,作为过程的一部分
函数。在第一个示例中,我通过调用元组的第一个元素删除了它:process.extractOne(x,choices)[0]
inplace=True
使排序值返回None
,因为您指定了在placetrue中执行排序的方法,我得到一个非类型对象,在删除InPlace后现在不可调用我编辑了代码我认为merge\u asof
只适用于整数。如果你不想找到一个字符串与另一个字符串最近的距离,你可以使用levenshtein距离,但我不知道Pandas库中有任何实现。我如何将其应用于两个dict?应该有两个。你能发布你的代码吗?太棒了!非常感谢你!如何返回%match?@TPguru您想将其作为新列吗?是的,将从FuzzyFuzzy导入过程中的替换为从rapidfuzz导入过程中的。您将看到在相同的结果下执行时间的大幅改进
from fuzzywuzzy import process
# create a choice list
choices = clist['Country'].values.tolist()
# apply fuzzywuzzy to each row using lambda expression
cdata['Close Country'] = cdata['Country'].apply(lambda x: process.extractOne(x, choices))
# add percent match wiht apply
cdata[['Close Country', 'Percent Match']] = cdata['Close Country'].apply(pd.Series)
# merge
cdata.merge(clist, left_on='Close Country', right_on='Country')
Country_x Close Country Percent Match Country_y BL?
0 Braizl Brazil 83 Brazil No
1 Rusia Russia 91 Russia Yes
2 us US 100 US No
cdata[['Close Country', 'Percent Match']] = cdata['Close Country'].apply(pd.Series)
cdata = cdata[cdata['Percent Match']>85]
merge = cdata.merge(clist, left_on='Close Country', right_on='Country')
merge[merge['Percent Match'] > 85]