在Pandas中从另一列提取子串新增列时出现报错该如何解决?
从DataFrame字符串列提取后缀子串的报错解决
问题场景
原始DataFrame:
import pandas as pd DF = pd.DataFrame({'files': ["S18-000344PAS", "S18-001850HE1", "S18-00344HE1"]})
需要新增stain列,提取files中数字后的后缀子串,最终结果:
DF = pd.DataFrame({'files': ["S18-000344PAS", "S18-001850HE1", "S18-00344HE1"], 'stain': ["PAS", "HE1", "HE1"]})
尝试代码及报错:
import re DF["Stain"] = DF.apply(lambda row: row.files[re.search(r'[a-zA-Z]{2,}', row.files).start():], axis=1)
报错信息:
AttributeError: 'NoneType' object has no attribute 'start'
错误原因
- 正则表达式匹配不准确:原正则
[a-zA-Z]{2,}会匹配字符串开头的字母(如S18中的S),不仅提取结果错误,若存在无符合模式的行,re.search会返回None。 - 未处理匹配失败的情况:当
re.search找不到匹配时返回None,调用start()方法就会触发AttributeError。
解决方案
方案1:修正正则并处理匹配失败
调整正则为匹配数字之后的字母+可选数字,同时增加判断避免None调用:
import re import pandas as pd DF = pd.DataFrame({'files': ["S18-000344PAS", "S18-001850HE1", "S18-00344HE1"]}) # 编译正则提升效率 pattern = re.compile(r'(?<=\d)[A-Za-z]+[0-9]*') DF["Stain"] = DF['files'].apply(lambda x: pattern.search(x).group() if pattern.search(x) else '')
方案2:使用pandas矢量化字符串方法(推荐)
用str.extract实现更简洁高效的矢量化操作,自动处理匹配失败的情况:
import pandas as pd DF = pd.DataFrame({'files': ["S18-000344PAS", "S18-001850HE1", "S18-00344HE1"]}) # 提取数字后的后缀,无匹配则返回NaN,再替换为空字符串 DF["Stain"] = DF['files'].str.extract(r'(?<=\d)([A-Za-z]+[0-9]*)', expand=False).fillna('')
说明
- 正则
(?<=\d)[A-Za-z]+[0-9]*的含义:(?<=\d)是正向断言,确保前面是数字;[A-Za-z]+匹配至少一个字母;[0-9]*匹配可选的数字(适配HE1这类场景)。 str.extract是pandas原生方法,比apply效率更高,适合批量处理DataFrame数据。
内容的提问来源于stack exchange,提问作者pill45
相关产品推荐
相关产品推荐

