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

Python TypeError:str.contains参数需为字符串或编译模式问题排查

问题描述

需求是判断names文件中的员工姓名是否存在于record文件中,若存在则提取对应员工编号。由于两个文件姓名格式不同(names名在前,record姓在前),已将names中的姓名拆分为n1、n2、n3、n4四列,需实现以下步骤:

  • 检查names中每位员工的n1、n2、n4、n3是否都出现在record的员工姓名字段中
  • 满足条件则标记姓名存在
  • 记录该姓名在record中的行号
  • 通过行号提取对应员工编号

其中record DataFrame的员工姓名字段在第8列,员工编号在第2列;names DataFrame拆分后的姓名字段在第2、3、4、5列。使用的循环代码如下:

for i in range(len(names)):
    x1 = record.index[record.iloc[:, 8].str.contains(names.iloc[i, 3])].values
    if x1.size > 0:
        x2 = record.index[record.iloc[:, 8].str.contains(names.iloc[i, 2])].values
        if x2.size > 0:
            if names.iloc[i, 4] is not None:
                x3 = record.index[record.iloc[:, 8].str.contains(names.iloc[i, 4])].values
                if x3.size > 0:
                    if names.iloc[i, 5] is not None:
                        x4 = record.index[record.iloc[:, 8].str.contains(names.iloc[i, 5])].values
                        if x4.size > 0:
                            flag = 1
                            loc = x4[0]
                        else:
                            flag = 0
                    else: 
                        flag = 1
                        loc = x3[0]
                else:
                    flag = 0
            else:
                flag = 1
                loc = x2[0]
        else:
            flag = 0
    else:
        flag = 0
                
    if flag == 1:
        names.iloc[i, 6] = record.iloc[loc,2]

执行时在第2行报错:

----> 2     x1 = record.index[record.iloc[:, 8].str.contains(names.iloc[i, 3])].values
TypeError: first argument must be string or compiled pattern
问题分析与解决

报错原因

str.contains()要求第一个参数必须是字符串或编译后的正则表达式,报错说明names.iloc[i,3]的值不是有效字符串——大概率是该位置为NaN、None,或者是数值类型等非字符串数据。

解决步骤

  1. 预处理姓名列:先将names中拆分后的姓名列(第2、3、4、5列)转换为字符串类型,并将空值/NaN替换为空字符串,避免传入无效参数:
# 转换为字符串并处理空值
names.iloc[:, [2,3,4,5]] = names.iloc[:, [2,3,4,5]].astype(str).replace({'nan': '', 'None': ''})
  1. 优化循环逻辑:在调用str.contains()前,先检查当前字段是否非空,同时简化嵌套结构,提升可读性:
for i in range(len(names)):
    # 获取当前员工的四个姓名片段并去除前后空格
    seg1 = names.iloc[i, 3].strip()
    seg2 = names.iloc[i, 2].strip()
    seg3 = names.iloc[i, 4].strip()
    seg4 = names.iloc[i, 5].strip()
    
    flag = 0
    loc = None
    
    # 先检查seg1是否存在
    if seg1:
        match1 = record.iloc[:, 8].str.contains(seg1, na=False)
        if match1.any():
            # 初始化匹配条件为seg1的结果
            combined_match = match1
            # 检查seg2是否存在并更新匹配条件
            if seg2:
                match2 = record.iloc[:, 8].str.contains(seg2, na=False)
                combined_match &= match2
                if not combined_match.any():
                    continue
            # 检查seg3是否存在并更新匹配条件
            if seg3:
                match3 = record.iloc[:, 8].str.contains(seg3, na=False)
                combined_match &= match3
                if not combined_match.any():
                    continue
            # 检查seg4是否存在并更新匹配条件
            if seg4:
                match4 = record.iloc[:, 8].str.contains(seg4, na=False)
                combined_match &= match4
                if not combined_match.any():
                    continue
            # 获取第一个匹配的行号
            loc = record.index[combined_match].values[0]
            flag = 1
    
    if flag == 1:
        names.iloc[i, 6] = record.iloc[loc, 2]
  1. 关键说明:
  • 使用na=False参数,避免record中姓名列的NaN值导致str.contains()返回NaN,引发索引错误
  • 用strip()去除姓名片段的前后空格,避免因空格导致匹配失败
  • 用&合并所有非空姓名片段的匹配条件,确保所有需要检查的片段都同时出现在record的姓名字段中,贴合需求逻辑

内容的提问来源于stack exchange,提问作者Meenakshi Seshagiri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:32:05