You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas匹配搜索字符串时用str.cat拼接部分Series条目及报错解决

Pandas匹配字符串时拼接Series条目并添加分隔符解决方案

问题背景

需要通过search_str中的关键词匹配calories列,匹配成功时更新test列内容。现有两种尝试存在问题:

  • 直接用+=拼接能实现功能,但拼接内容之间没有分隔符(比如空格),结果会变成not_yet_setSTRAUSSSTREET这种混乱格式
  • 尝试用str.cat方法时触发报错:ValueError: Did you mean to supply a sep keyword?,且无法仅对匹配行执行拼接操作

报错原因

原代码中使用str.cat的方式存在两个核心问题:

  1. str.cat直接对整个test Series操作,而非仅匹配关键词的行,导致赋值时维度不匹配
  2. 未区分初始值(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 03:37:50