如何在Pandas两列中替换多个复杂字符并解决re.error报错
问题:Pandas DataFrame替换指定字符报错解决
需要在Pandas DataFrame的From和to列中,替换所有+符号以及列表S=['H2O','NADP(+)','NADPH','NAD(+)', 'NADH', 'H(+)']中的字符,但运行代码时出现re.error: nothing to repeat at position 2报错。
原始数据与错误代码
数据定义
import pandas as pd classes = [('2.7.2.3', 'a primary alcohol', 'an aldehyde'), ('2.7.1.3', 'a secondary alcohol', 'a ketone'), ('3.1.1.3', 'an aldehyde + NADP(+)', 'a 3-oxoacyl-[ACP] + NADPH'), ('3.1.1.3', '3-oxoacyl-[ACP] + NAD(+)', '2,3-dioxo-L-gulonate + NADH'), ('2.7.2.3', 'D-ribitol 5-phosphate + NADP(+)', 'a primary alcohol + H(+)'), ('1.7.99.4', '2,3-dioxo-L-gulonate + NAD(+)', 'D-ribulose 5-phosphate + NADH'), ('1.1.1.304', 'L-iditol + NAD(+)', ' H(+) + keto-L-sorbose + NADH'), ('2.7.4.3', 'H2O', 'oxidized coenzyme F420-1'), ('4.1.1.68', 'myo-inositol + NAD(+)', ' H(+) + NADH + a secondary alcohol')] labels = ['Ko_EC','From', 'to'] alls = pd.DataFrame.from_records(classes, columns=labels)
错误代码
alls['From'] = alls['From'].str.replace("+", "") alls['to'] = alls['to'].str.replace("+", "") S = ['H2O','NADP()','NADPH','NAD()', 'NADH', 'H()'] alls
报错信息
re.error: nothing to repeat at position 2
期望结果
Ko_EC From to 0 2.7.2.3 a primary alcohol an aldehyde 1 2.7.1.3 a secondary alcohol a ketone 2 3.1.1.3 an aldehyde a 3-oxoacyl-[ACP] 3 3.1.1.3 3-oxoacyl-[ACP] 2,3-dioxo-L-gulonate 4 2.7.2.3 D-ribitol 5-phosphate a primary alcohol 5 1.7.99.4 2,3-dioxo-L-gulonate D-ribulose 5-phosphate 6 1.1.1.304 L-iditol keto-L-sorbose 7 2.7.4.3 oxidized coenzyme F420-1 8 4.1.1.68 myo-inositol a secondary alcohol
问题原因
+是正则表达式的特殊字符(表示匹配前序字符1次或多次),直接用str.replace会被当作正则语法解析,导致报错。- 原代码未正确处理目标列表中的字符,也没考虑
+前后的空格,无法达到期望的替换效果。
解决方案
修正后代码
import pandas as pd import re # 数据定义(同原始数据) classes = [('2.7.2.3', 'a primary alcohol', 'an aldehyde'), ('2.7.1.3', 'a secondary alcohol', 'a ketone'), ('3.1.1.3', 'an aldehyde + NADP(+)', 'a 3-oxoacyl-[ACP] + NADPH'), ('3.1.1.3', '3-oxoacyl-[ACP] + NAD(+)', '2,3-dioxo-L-gulonate + NADH'), ('2.7.2.3', 'D-ribitol 5-phosphate + NADP(+)', 'a primary alcohol + H(+)'), ('1.7.99.4', '2,3-dioxo-L-gulonate + NAD(+)', 'D-ribulose 5-phosphate + NADH'), ('1.1.1.304', 'L-iditol + NAD(+)', ' H(+) + keto-L-sorbose + NADH'), ('2.7.4.3', 'H2O', 'oxidized coenzyme F420-1'), ('4.1.1.68', 'myo-inositol + NAD(+)', ' H(+) + NADH + a secondary alcohol')] labels = ['Ko_EC','From', 'to'] alls = pd.DataFrame.from_records(classes, columns=labels) # 定义需要替换的目标列表 targets = ['H2O','NADP(+)','NADPH','NAD(+)', 'NADH', 'H(+)'] # 生成正则匹配模式:匹配目标字符及前后空格,转义特殊字符避免正则错误 pattern = r'\s*(?:{})\s*'.format('|'.join([re.escape(t) for t in targets])) # 批量处理From和to列 for col in ['From', 'to']: # 替换目标列表中的字符 alls[col] = alls[col].str.replace(pattern, '', regex=True) # 替换剩余的+符号及前后空格 alls[col] = alls[col].str.replace(r'\s*\+\s*', '', regex=True) # 清理首尾多余空格 alls[col] = alls[col].str.strip() print(alls)
代码说明
re.escape(t):转义目标字符中的特殊符号(如()),避免正则语法解析错误。r'\s*(?:{})\s*':匹配目标字符前后的任意空格,非捕获组避免生成额外匹配内容。- 先替换目标列表中的字符,再清理残留的
+和空格,最后去除首尾空格,确保结果符合预期。
运行结果
Ko_EC From to 0 2.7.2.3 a primary alcohol an aldehyde 1 2.7.1.3 a secondary alcohol a ketone 2 3.1.1.3 an aldehyde a 3-oxoacyl-[ACP] 3 3.1.1.3 3-oxoacyl-[ACP] 2,3-dioxo-L-gulonate 4 2.7.2.3 D-ribitol 5-phosphate a primary alcohol 5 1.7.99.4 2,3-dioxo-L-gulonate D-ribulose 5-phosphate 6 1.1.1.304 L-iditol keto-L-sorbose 7 2.7.4.3 oxidized coenzyme F420-1 8 4.1.1.68 myo-inositol a secondary alcohol
内容的提问来源于stack exchange,提问作者yan wang
相关产品推荐
相关产品推荐

