基于其他列更新Pandas列值的技术求助
Solution for Conditionally Updating Alias Column Based on Substring Match
Hey Chris, 我太理解你刚接触Pandas时,想通过子串匹配来更新列的挫败感了——各种loc、循环、where方法试了个遍,要么不对要么出奇怪的bug,确实头疼。不过你最后摸索出来的这个结合fuzzywuzzy的解法真的很实用,我来帮你拆解一下这个思路,再给你点优化建议让它更稳健:
你的问题回顾
你需要根据两个DataFrame的列来更新df1.Alias:当df2.Alias的值是df1.Company的子串时,将df1.Alias赋值为对应的df2.Alias;如果df2.Alias是np.nan(比如The Shoe Company的条目),则保留df1.Alias的原有空值。
你的示例数据集:
import pandas as pd import numpy as np from fuzzywuzzy import process # 需提前安装: pip install fuzzywuzzy # 主数据集 d = { 'Company': ['The Cool Company Inc', 'Cool Company, Inc', 'The Cool Company', 'The Shoe Company', 'Muffler Store', 'Muffler Store'], 'Position': ['Cool Job A', 'Cool Job B', 'Cool Job C', 'Salesman', 'Sales', 'Technician'], 'City': ['Tacoma', 'Tacoma','Tacoma', 'Boulder', 'Chicago', 'Chicago'], 'State': ['AZ', 'AZ', 'AZ', 'CO', 'IL', 'IL'], 'Alias': [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan] } df1 = pd.DataFrame(d) # 别名参考数据集 d2 = { 'Company': ['The Cool Company, Inc.', 'The Shoe Company', 'Muffler Store LLC'], 'Alias': ['Cool Company', np.nan, 'Muffler'], 'First Name': ['Carol', 'James', 'Frankie'], 'Last Name': ['Fisher', 'Smith', 'Johnson'] } df2 = pd.DataFrame(d2)
你找到的有效解法
你通过以下两步实现了需求:
- 提取
df2.Alias的唯一值,减少重复匹配:
aliases = df2.Alias.unique()
- 使用
apply结合process.extract匹配子串并更新列:
df1['Alias'] = df1.Company.apply(lambda x: [process.extract(x, aliases, limit=1)][0][0][0])
思路拆解
- 提取唯一别名:
df2.Alias.unique()过滤了重复的别名值,既提升了匹配效率,也保留了np.nan(对应不需要别名的条目)。 - 模糊子串匹配:
fuzzywuzzy的process.extract会计算字符串间的相似度(默认用Levenshtein距离),能很好识别子串包含关系(比如Cool Company是The Cool Company Inc的子串,匹配度会很高)。limit=1确保只返回最匹配的结果。 - Lambda取值:
[process.extract(...)][0][0][0]是从返回的匹配结果元组(格式为(匹配值, 匹配度))中提取出我们需要的别名字符串。
优化建议(让解法更稳健)
你的解法已经能满足需求,但可以做一点调整来避免误匹配:
- 先过滤掉
aliases中的np.nan,避免无效匹配:
aliases = df2.Alias.dropna().unique()
- 添加匹配度阈值,只有当匹配度足够高时才赋值,否则保留原空值:
df1['Alias'] = df1.Company.apply( lambda x: process.extractOne(x, aliases)[0] if process.extractOne(x, aliases)[1] > 80 else np.nan )
这里设置的阈值80可以根据你的数据情况调整,确保只有真正的子串匹配才会被赋值,避免把不相关的字符串误填进去。
另外,如果你觉得fuzzywuzzy的匹配速度不够快,可以安装python-Levenshtein库来加速:
pip install python-Levenshtein
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

