如何在Python Pandas中使用通配符*合并两个DataFrame
实现带通配符的DataFrame匹配(类似Excel VLOOKUP的*功能)
问题核心
pd.merge会将*当作普通字符处理,无法实现Excel VLOOKUP中*匹配任意长度字符的效果,需通过正则转换实现对应逻辑。
解决方案步骤
Excel通配符转正则:
- Excel的
*对应正则.*(匹配任意长度字符) - Excel的
?对应正则.(匹配单个字符) - 先转义原字符串中的正则特殊字符(如
.,+),避免干扰匹配逻辑
- Excel的
两种匹配实现方式:
- 逐行匹配:高效,按查找表顺序返回第一个匹配项(和Excel VLOOKUP行为完全一致)
- 交叉连接过滤:直观,适合小数据量场景
代码示例
1. 构造测试数据
import pandas as pd import re # 带通配符的查找表(类似VLOOKUP的查找区域) df_wildcard = pd.DataFrame({ 'pattern': ['A*', 'B*C', 'X?Y'], 'value': [10, 20, 30] }) # 需要匹配的目标数据 df_target = pd.DataFrame({ 'text': ['Apple', 'BananaC', 'AXY', 'Hello', 'BXXC'] })
2. 通配符转正则工具函数
def excel_wildcard_to_regex(pattern): # 先转义所有正则特殊字符,再替换Excel通配符为正则语法 escaped = re.escape(pattern) return escaped.replace(r'\*', '.*').replace(r'\?', '.') # 生成正则模式列 df_wildcard['regex_pattern'] = df_wildcard['pattern'].apply(excel_wildcard_to_regex)
3. 方法一:逐行匹配(推荐,高效匹配首个符合项)
def get_matched_val(text): # 按查找表顺序遍历,返回第一个匹配的值 for _, row in df_wildcard.iterrows(): if re.match(row['regex_pattern'], text): return row['value'] return None # 无匹配时返回空值 # 为目标数据添加匹配结果列 df_target['matched_value'] = df_target['text'].apply(get_matched_val)
4. 方法二:交叉连接后过滤(直观,小数据适用)
# 交叉连接两个DataFrame cross_join = df_target.assign(temp_key=1).merge(df_wildcard.assign(temp_key=1), on='temp_key').drop('temp_key', axis=1) # 过滤出匹配的行 matched_rows = cross_join[cross_join.apply(lambda x: re.match(x['regex_pattern'], x['text']), axis=1)] # 按目标文本分组,取第一个匹配结果(模拟VLOOKUP首次匹配逻辑) result = matched_rows.groupby('text').first().reset_index()
输出结果
执行方法一后,df_target的最终输出:
| text | matched_value |
|---|---|
| Apple | 10 |
| BananaC | 20 |
| AXY | 10 |
| Hello | None |
| BXXC | 20 |
内容的提问来源于stack exchange,提问作者Vaibhav Patil
相关产品推荐
相关产品推荐

