使用np.select为含多字符串的pandas DataFrame单元格条件赋值
解决方案
核心原理是np.select会按照传入条件列表的先后顺序从高到低匹配优先级:某一行一旦满足靠前的条件,就会直接取对应的值,不会再执行后续条件判断。你不需要枚举所有字符串组合,只要按规则优先级从高到低排列条件即可,天然适配单元格多字符串的场景,扩展性极强。
你的赋值规则优先级从高到低排序如下:
- 最高优先级:单元格包含
Three,直接赋值'3' - 次优先级:单元格包含
One且不包含Three,赋值'1' - 其余原有规则按优先级顺延即可
注意:因为最高优先级已经把所有包含Three的行提前匹配完成,走到次优先级判断的行天然满足「不包含Three」的要求,不需要额外写链式AND条件做排除。
实现代码
原有生成关键词布尔列的逻辑可以完全保留,只需要调整conditions列表的顺序即可:
import pandas as pd import numpy as np data = ['One', 'Two', ['One', 'Four'], 'One', ['Three', 'One', 'Four']] my_df = pd.DataFrame(data, columns=['test']) # 原有单关键词布尔列生成逻辑 my_df["one"] = my_df["test"].apply(lambda x: 'One' in x) my_df["two"] = my_df["test"].apply(lambda x: 'Two' in x) my_df["three"] = my_df["test"].apply(lambda x: 'Three' in x) my_df["four"] = my_df["test"].apply(lambda x: 'Four' in x) # 按优先级从高到低排列条件 conditions = [ my_df["three"], # 最高优先级:含Three直接赋值3 my_df["one"], # 次优先级:不含Three但含One赋值1 my_df["two"], my_df["four"], ] values = ['3', '1', '2', '4'] my_df['new'] = np.select(conditions, values) print(my_df)
运行结果
执行后输出完全符合预期:
test one two three four new 0 One True False False False 1 1 Two False True False False 2 2 [One, Four] True False False True 1 3 One True False False False 1 4 [Three, One, Four] True False True True 3
扩展优化
如果你的关键词数量很多,不需要手写每个关键词的apply判断,可以通过循环批量生成布尔列,后续新增关键词只要加到关键词列表里即可:
# 所有需要识别的关键词统一维护在这里 keywords = ['One', 'Two', 'Three', 'Four'] for kw in keywords: my_df[kw.lower()] = my_df["test"].apply(lambda x: kw in x)
后续新增赋值规则时,只要确定新规则的优先级,把对应判断条件插入到conditions列表的对应位置,同时在values列表对应位置加上目标赋值即可,完全不需要考虑单元格内的字符串组合情况。
内容的提问来源于stack exchange,提问作者Beatdown
相关产品推荐
相关产品推荐

