Pandas实现SQL CASE WHEN逻辑 按优先级匹配标签生成新列
问题说明
你需要实现类似SQL的优先级CASE WHEN逻辑,给pandas的DataFrame新增Tag_after列,匹配规则按优先级从高到低执行,每行匹配到第一个符合的规则后就不再后续匹配,未匹配到规则的行保留原始Tag值。
错误原因
- 尝试1:每次匹配都会覆盖所有命中当前规则的行,不管该行是否已经匹配到更高优先级的规则,最终低优先级规则会覆盖高优先级的匹配结果,不符合优先级要求。
- 尝试2:
if tag_before[i] in df[col_tag]:的判断逻辑错误,该语法是判断字符串是否存在于Series的索引中,不是判断每行的Tag字段是否包含对应字符串,完全不符合匹配要求。
正确实现代码
import pandas as pd # 构造原始数据 df = pd.DataFrame.from_dict( { 'Name': ['Jane', 'Melissa', 'John', 'Matt', 'Abernethy', 'Annie', 'Brook', 'Brian', 'Carrie'], 'Tag': ['tag1,tag2', 'tag9,tag_wrong1', 'tag4,tag3,tag7', 'tag2,tag9', 'tag1,tag3', 'tag3,tag4,tag5', 'tag9,tag2', 'tag3,tag2', 'tag1,tag5'], } ) # 按优先级从高到低定义匹配规则:(要匹配的tag关键字, 替换后的tag值) tag_rule = [ ('tag1', 'tag1'), ('tag2', 'tag2'), ('tag3', 'tag3'), ('tag4', 'tag4'), ('tag5', 'tag5'), ('tag_wrong1', 'tag_right1'), ] # 初始化结果列为空 df['Tag_after'] = '' # 按优先级遍历规则,仅给还未匹配到结果的行赋值 for match_tag, replace_tag in tag_rule: # 筛选条件:结果列为空 且 Tag列包含当前匹配关键字(na=False处理空值情况) match_mask = (df['Tag_after'] == '') & df['Tag'].str.contains(match_tag, na=False) df.loc[match_mask, 'Tag_after'] = replace_tag # 未匹配到任何规则的行,保留原始Tag值 df.loc[df['Tag_after'] == '', 'Tag_after'] = df['Tag']
运行结果验证
执行代码后输出的df和你期望的结果完全一致:
| 序号 | Name | Tag | Tag_after |
|---|---|---|---|
| 0 | Jane | tag1,tag2 | tag1 |
| 1 | Melissa | tag9,tag_wrong1 | tag_right1 |
| 2 | John | tag4,tag3,tag7 | tag3 |
| 3 | Matt | tag2,tag9 | tag2 |
| 4 | Abernethy | tag1,tag3 | tag1 |
| 5 | Annie | tag3,tag4,tag5 | tag3 |
| 6 | Brook | tag9,tag2 | tag2 |
| 7 | Brian | tag3,tag2 | tag3 |
| 8 | Carrie | tag1,tag5 | tag1 |
内容的提问来源于stack exchange,提问作者Roc-kit
相关产品推荐
相关产品推荐

