如何使用pandas移除DataFrame指定列开头的预设特殊字符
问题解答
1 原有循环代码的bug原因
- 直接触发原因:待处理的
2*VEDGE-CAB-C13-XXX字符串开头存在空格,调用startswith('2*')时无法匹配成功,因此没有触发替换逻辑。 - 隐藏的逻辑错误:内层循环的索引
j仅在匹配失败时才自增,匹配成功时j不会递增,会导致后续遍历的元素和索引错位,匹配次数较多时会出现大范围的索引对应错误。当前示例中刚好只有这一个字符串因为前缀空格未匹配,其余匹配逻辑未触发明显的索引错位,才显得只有这一处异常。
2 pandas矢量化实现方案
由于需要移除的前缀包含*、(等正则特殊字符,需要先对前缀做转义处理,同时为了避免短前缀优先匹配导致长前缀失效,需要先将前缀按长度降序排序,实现代码如下:
import pandas as pd import re # 原有数据定义不变 df_s1 = pd.DataFrame({'Part Number' : ['(2)CAB-ETHS-RJ45',' 2*VEDGE-CAB-C13-XXX','(4X)CAB-ETHXOVER','1*VEDGE-ABCD','2*73ETHER-387','4xCBTA-98CD','5xNBOC','(1)289RG7','2 CDXG59','(7x)29FG2ZT-AB','((*2)FGDT-X78','((4))RGD-RX78','EDXC-Y82','D92ZT-3A','FTZT-9A7'], 'ID' : ['1','2','3','4','4','4','4','4','4','4','4','5','4','4','6'] }) df_s2 = pd.DataFrame({'Special Charater':['(2)','2*','(4X)','1*','4x','5x','(1)','2 ','(7x)','((*2)','((4))']}) # 步骤1:前缀按长度降序排序,避免短前缀先匹配导致长前缀失效 prefixes = df_s2['Special Charater'].sort_values(key=lambda x: x.str.len(), ascending=False) # 步骤2:转义每个前缀的正则特殊字符,拼接成仅匹配开头的正则模式 pattern = r'^(' + '|'.join(re.escape(p) for p in prefixes) + ')' # 步骤3:批量替换开头匹配的前缀为空 df_s1['Part Number'] = df_s1['Part Number'].str.replace(pattern, '', regex=True)
如果需要先去除字符串开头的空格再匹配前缀,可将第三步修改为:
df_s1['Part Number'] = df_s1['Part Number'].str.lstrip().str.replace(pattern, '', regex=True)
修改后之前匹配失败的带空格的2*VEDGE-CAB-C13-XXX也可以正常移除前缀。
内容的提问来源于stack exchange,提问作者Vishav Gupta
相关产品推荐
相关产品推荐

