Pandas匹配搜索字符串时用str.cat拼接部分Series条目及报错解决
Pandas匹配字符串时拼接Series条目并添加分隔符解决方案
问题背景
需要通过search_str中的关键词匹配calories列,匹配成功时更新test列内容。现有两种尝试存在问题:
- 直接用
+=拼接能实现功能,但拼接内容之间没有分隔符(比如空格),结果会变成not_yet_setSTRAUSSSTREET这种混乱格式 - 尝试用
str.cat方法时触发报错:ValueError: Did you mean to supply asepkeyword?,且无法仅对匹配行执行拼接操作
报错原因
原代码中使用str.cat的方式存在两个核心问题:
str.cat直接对整个testSeries操作,而非仅匹配关键词的行,导致赋值时维度不匹配- 未区分初始值(
not_yet_set)和已拼接的值,会导致初始值被错误拼接成not_yet_set,STRAUSS这种不符合需求的结果
可行解决方案
方法1:基于apply的条件拼接(简单直观)
通过匹配掩码定位目标行,对每行的test值做判断:如果是初始值则直接替换为关键词,否则添加分隔符(比如空格)后拼接关键词。代码如下:
import pandas as pd search_str = ['STRAUSS', 'STREET', "STUBBY'S"] data = { "calories": ['STRAUSS_STREET', 'ten', 'twenty'], "duration": [50, 40, 45], "test": ['not_yet_set', 'not_yet_set', 'not_yet_set'] } df_1 = pd.DataFrame(data) df_1["calories"] = df_1["calories"].astype(pd.StringDtype) for keyword in search_str: # 生成匹配掩码:定位calories包含当前关键词的行 mask = df_1['calories'].str.contains(keyword) # 对匹配行的test列做条件拼接 df_1.loc[mask, 'test'] = df_1.loc[mask, 'test'].apply( lambda x: keyword if x == 'not_yet_set' else f"{x} {keyword}" ) print(df_1)
运行结果:
calories duration test 0 STRAUSS_STREET 50 STRAUSS STREET 1 ten 40 not_yet_set 2 twenty 45 not_yet_set
方法2:优化版str.cat用法(向量化操作)
如果偏好使用str.cat,可以构造和原Series长度一致的关键词序列,仅在匹配行填充关键词+分隔符,其余行填充空字符串,再执行拼接:
import pandas as pd search_str = ['STRAUSS', 'STREET', "STUBBY'S"] data = { "calories": ['STRAUSS_STREET', 'ten', 'twenty'], "test": ['not_yet_set', 'not_yet_set', 'not_yet_set'] } df_1 = pd.DataFrame(data) df_1["calories"] = df_1["calories"].astype(pd.StringDtype) for keyword in search_str: mask = df_1['calories'].str.contains(keyword) # 构造关键词序列:匹配行填充" 关键词",其余行填充空字符串 keyword_seq = pd.Series(['']*len(df_1)) keyword_seq[mask] = f" {keyword}" # 执行拼接 df_1['test'] = df_1['test'].str.cat(keyword_seq, sep='') # 替换掉初始值前的无效前缀 df_1['test'] = df_1['test'].apply(lambda x: x.replace('not_yet_set ', '') if 'not_yet_set ' in x else x) print(df_1)
这个方法同样能得到和方法1一致的结果,适合习惯向量化操作的场景。
内容的提问来源于stack exchange,提问作者wiseass
相关产品推荐
相关产品推荐

