如何基于列的文本相似度合并两个Python DataFrame?
解决不同格式国家名称的DataFrame合并问题
输入数据
df1结构:
country_1 column1 united states of america abcd Ireland (Republic of Ireland) efgh Korea Rep Of fsdf Switzerland (Swiss Confederation) dsaa
df2结构:
country_2 column2 united states cdda Ireland ddgd South Korea rewt Switzerland tuut
期望输出:
country_1 column1 country_2 column2 united states of america abcd united states cdda Ireland (Republic of Ireland) efgh Ireland ddgd Korea Rep Of fsdf South Korea rewt Switzerland (Swiss Confederation) dsaa Switzerland tuut
解决方案
方法1:模糊字符串匹配(fuzzywuzzy)
普通字符串匹配和正则无法处理这种全称/简称的差异,模糊匹配通过计算字符串相似度匹配对应条目。
- 安装依赖:
pip install fuzzywuzzy python-Levenshtein
- 实现代码:
import pandas as pd from fuzzywuzzy import process # 构造示例DataFrame df1 = pd.DataFrame({ 'country_1': ['united states of america', 'Ireland (Republic of Ireland)', 'Korea Rep Of', 'Switzerland (Swiss Confederation)'], 'column1': ['abcd', 'efgh', 'fsdf', 'dsaa'] }) df2 = pd.DataFrame({ 'country_2': ['united states', 'Ireland', 'South Korea', 'Switzerland'], 'column2': ['cdda', 'ddgd', 'rewt', 'tuut'] }) # 为df2的每个国家匹配df1中最相似的条目 def match_country(country): match, score = process.extractOne(country, df1['country_1']) # 可根据需求设置相似度阈值(如score>80才匹配),示例直接取最高相似度结果 return match df2['country_1'] = df2['country_2'].apply(match_country) # 合并并调整列顺序 result = pd.merge(df1, df2, on='country_1', how='left') result = result[['country_1', 'column1', 'country_2', 'column2']] print(result.to_string(index=False))
方法2:pycountry标准化国家名称
利用pycountry将不同格式的国家名称转换为统一的ISO标准代码,通过标准代码合并准确性更高。
- 安装依赖:
pip install pycountry
- 实现代码:
import pandas as pd import pycountry # 构造示例DataFrame df1 = pd.DataFrame({ 'country_1': ['united states of america', 'Ireland (Republic of Ireland)', 'Korea Rep Of', 'Switzerland (Swiss Confederation)'], 'column1': ['abcd', 'efgh', 'fsdf', 'dsaa'] }) df2 = pd.DataFrame({ 'country_2': ['united states', 'Ireland', 'South Korea', 'Switzerland'], 'column2': ['cdda', 'ddgd', 'rewt', 'tuut'] }) # 将国家名称转换为ISO 3166-1 alpha-2代码 def get_country_code(country_name): try: country = pycountry.countries.search_fuzzy(country_name)[0] return country.alpha_2 except: return None # 添加标准代码列 df1['country_code'] = df1['country_1'].apply(get_country_code) df2['country_code'] = df2['country_2'].apply(get_country_code) # 通过标准代码合并并调整列顺序 result = pd.merge(df1, df2, on='country_code', how='left') result = result[['country_1', 'column1', 'country_2', 'column2']] print(result.to_string(index=False))
说明
- 模糊匹配适合名称差异大的场景,但需设置合理相似度阈值避免错配;
- pycountry标准化方法准确性更高,但对部分非标准名称可能无法匹配,需额外处理特殊情况。
内容的提问来源于stack exchange,提问作者noodcoder
相关产品推荐
相关产品推荐

