
本文介绍如何使用df.apply(axis=1)高效实现跨所有列的关键词模糊匹配,为dataframe添加布尔标志列,避免逐列覆盖错误,并确保非字符串类型安全转换。
本文介绍如何使用df.apply(axis=1)高效实现跨所有列的关键词模糊匹配,为dataframe添加布尔标志列,避免逐列覆盖错误,并确保非字符串类型安全转换。
在实际数据处理中,常需基于多个文本列判断是否包含任意指定关键词(如 'sp'、'xyz'),并统一生成一个二值标志列(1 表示匹配,0 表示不匹配)。若采用循环逐列赋值(如 for col in df.columns: df['flag'] = ...),后一次赋值会完全覆盖前一次结果,最终仅反映最后一列的匹配状态——这正是原问题中出现全 0 的根本原因。
正确做法是按行(axis=1)整体扫描:对每一行,遍历其所有列值,检查是否存在任一关键词子串。关键要点如下:
- 使用 df.apply(..., axis=1) 遍历行,而非列;
- 在 lambda 中嵌套双重生成器表达式:for col in df.columns × for keyword in keywords;
- 对每个单元格值显式转为字符串(str(row[col])),防止 TypeError(如数值、None 等非字符串类型);
- 利用 any() 实现短路逻辑:一旦匹配即返回 True,提升效率。
以下是完整可运行示例:
import pandas as pd
# 构建示例数据
data = {
'column1': ['sp123', 'abc', 'sp456', 'def'],
'column2': ['tp1234', 'abc', 'sp4256', 'def'],
'column3': ['syp123', 'abc', 'sp456', 'def']
}
df = pd.DataFrame(data)
keywords = ['sp', 'xyz']
# ✅ 正确:跨所有列按行匹配
df['flag'] = df.apply(
lambda row: 1 if any(
keyword in str(row[col]) for col in df.columns for keyword in keywords
) else 0,
axis=1
)
print(df)输出结果:
column1 column2 column3 flag 0 sp123 tp1234 syp123 1 1 abc abc abc 0 2 sp456 sp4256 sp456 1 3 def def def 0
⚠️ 注意事项:
- 若关键词需精确匹配(而非子串),请将 keyword in str(...) 替换为 str(row[col]) == keyword;
- 如需忽略大小写,可统一转小写:keyword.lower() in str(row[col]).lower();
- 大数据集下,apply(axis=1) 性能低于向量化操作;若仅需单列匹配,优先用 df['col'].str.contains(..., regex=False).astype(int);但多列联合逻辑仍以 apply 最直观可靠。
该方法兼顾简洁性、可读性与鲁棒性,是 Pandas 中实现动态多列条件标记的标准实践。

















