Google Sheets与Python模糊匹配求助:两列部分匹配实现失败
解决两列数据部分匹配问题
Google Sheets 解决方案
你之前用的VLOOKUP公式无法实现双向任意位置的部分匹配,因为VLOOKUP的通配符仅支持前缀匹配。以下是可行的公式方案:
通用双向部分匹配公式
在结果列第一个单元格(比如C2)输入,下拉填充即可:
=IF(OR(COUNTIF(B:B,"*"&A2&"*"),COUNTIF(A:A,"*"&B2&"*")), "EXISTS", "")
- 逻辑:用
COUNTIF搭配通配符*,检查B列是否存在包含A列当前值的内容,或A列是否存在包含B列当前值的内容,满足任一条件返回EXISTS。
针对示例场景的优化公式
如果你的数据存在类似「A列是B列值的扩展(如alpha.roadsgs.eval包含alpha.roadsgs)」的固定规律,可以针对性调整:
=IF(OR(COUNTIF(B:B,"*"&LEFT(A2,FIND(".eval",A2)-1)&"*"), COUNTIF(A:A,"*"&B2&"*")), "EXISTS", "")
这个公式会提取A列中.eval之前的片段,去匹配B列内容,更贴合你给出的示例数据。
Python(Colab)解决方案
你之前的代码存在几个问题:pip install在Colab中需要加感叹号、未定义df1/df2、未导入difflib、空值(NaN,类型为float)导致匹配函数报错。以下是修正后的两种方案:
方案1:精确字符串包含匹配
import pandas as pd # 读取数据 data = pd.read_csv('/delta.csv') df = pd.DataFrame(data[['Current', 'Combined']]) # 对应你的ColA和ColB列 # 处理空值,将NaN转为空字符串 df['Current'] = df['Current'].fillna('') df['Combined'] = df['Combined'].fillna('') # 定义部分匹配判断函数 def check_partial_match(row): col_a = row['Current'] col_b = row['Combined'] # 检查B列值是否在A列中,或A列值是否在B列中 if col_b != '' and col_b in col_a: return 'EXISTS' elif col_a != '' and col_a in col_b: return 'EXISTS' # 额外处理A列是B列扩展的场景(如示例中的.eval后缀) elif col_b != '' and col_b in col_a.split('.eval')[0]: return 'EXISTS' else: return '' # 生成结果列 df['result'] = df.apply(check_partial_match, axis=1) print(df)
方案2:模糊相似度匹配(fuzzywuzzy)
如果需要处理非精确的相似匹配(比如拼写近似),可以用fuzzywuzzy:
import pandas as pd !pip install fuzzywuzzy python-Levenshtein # 安装依赖,python-Levenshtein加速匹配 from fuzzywuzzy import fuzz # 读取并预处理数据 data = pd.read_csv('/delta.csv') df = pd.DataFrame(data[['Current', 'Combined']]) df['Current'] = df['Current'].fillna('') df['Combined'] = df['Combined'].fillna('') # 定义模糊匹配函数(设置相似度阈值为80,可调整) def check_fuzzy_match(row): col_a = row['Current'] col_b = row['Combined'] if col_a == '' or col_b == '': # 空值场景:检查当前值是否在另一列的非空值中有高相似度匹配 matches = [val for val in df['Combined'].dropna() if fuzz.partial_ratio(col_a, val) >= 80] return 'EXISTS' if matches else '' elif fuzz.partial_ratio(col_a, col_b) >= 80: return 'EXISTS' else: return '' # 生成结果列 df['result'] = df.apply(check_fuzzy_match, axis=1) print(df)
内容的提问来源于stack exchange,提问作者user262503
相关产品推荐
相关产品推荐

