基于部分字符串匹配合并Pandas DataFrame的技术实现需求
基于子字符串匹配的DataFrame合并方案(保留object类型)
要实现你需要的部分字符串匹配合并,同时保留所有列的object类型,这里提供两种可行方案:
方案一:逐行匹配(小数据集友好)
通过自定义函数结合apply,逐行检查地址字符串是否包含目标城镇名称,匹配成功则关联对应的区域代码:
import pandas as pd # 定义原始DataFrame clr_null = pd.DataFrame({'Address Line': ['DUBLIN 10', 'CITY', 'DUBLIN 10 CITY']}) area = pd.DataFrame({'town': ['DUBLIN 10', 'DUBLIN 11', 'DUBLIN 12'], 'area': ['D10', 'D11', 'D12']}) # 自定义匹配函数:返回第一个匹配的区域代码,无匹配则返回pd.NA(保持object类型) def match_area(address): for _, row in area.iterrows(): if row['town'] in address: return row['area'] return pd.NA # 生成结果列 clr_null['area'] = clr_null['Address Line'].apply(match_area) # 输出结果 print(clr_null)
执行后得到的结果完全符合预期:
Address Line area 0 DUBLIN 10 D10 1 CITY <NA> 2 DUBLIN 10 CITY D10
关键说明:
- 使用
pd.NA作为缺失值标记,确保area列维持object类型(若用np.nan会自动转为float类型) - 按
area的行顺序匹配,若地址同时包含多个城镇名称,会返回第一个匹配的结果
方案二:矢量化匹配(大数据集友好)
利用pandas的字符串处理能力实现矢量化匹配,避免循环,大幅提升大数据量下的效率:
import pandas as pd # 定义原始DataFrame clr_null = pd.DataFrame({'Address Line': ['DUBLIN 10', 'CITY', 'DUBLIN 10 CITY']}) area = pd.DataFrame({'town': ['DUBLIN 10', 'DUBLIN 11', 'DUBLIN 12'], 'area': ['D10', 'D11', 'D12']}) # 用正则表达式提取地址中匹配的城镇名称 clr_null['matched_town'] = clr_null['Address Line'].str.extract( f"({'|'.join(area['town'])})", expand=False ) # 合并数据并清理临时列 result = clr_null.merge( area[['town', 'area']], left_on='matched_town', right_on='town', how='left' ).drop(['matched_town', 'town'], axis=1) # 确保area列维持object类型 result['area'] = result['area'].astype('object').where(result['area'].notna(), pd.NA) # 输出结果 print(result)
关键说明:
- 用
str.extract结合正则表达式批量提取匹配的城镇,效率远高于循环 - 最后通过
astype('object')和pd.NA确保列类型符合要求
内容的提问来源于stack exchange,提问作者Alex Santini
相关产品推荐
相关产品推荐

