如何通过正则命名捕获组对比删除Pandas DataFrame不匹配行
解决Pandas DataFrame中按正则命名捕获组匹配过滤行的问题
我有一个包含两列字符串的Pandas DataFrame,想要删除Resources列与ServicePlan列通过正则匹配后,命名捕获组termduration结果不匹配的行。
示例数据
ServicePlan Resources 0 Plan A (CSP COM BAS 1YR ANN) Resource A (CSP COM BAS 1YR ANN) 1 Plan A (CSP COM BAS 1YR ANN) Resource B (CSP COM BAS 1YR ANN) 2 Plan A (CSP COM BAS 1YR ANN) Resource C (CSP COM BAS 6YR ANN)
我尝试的代码(出现类型错误)
import pandas as pd import re e_name = r'(?P<name>.*)\((?P<product>[A-Z]{3})\s(?P<type>[A-Z]{3})\s?(?P<baseattach>BAS|ADD|ATT|SWS)?\s?(?P<telco_overusage>OVG)?\s?(?P<termduration>[A-Z0-9]{3})?\s?(?P<billing>[A-Z0-9]{3})\)$' name_re = re.compile(e_name) data = {'ServicePlan': ["Plan A (CSP COM BAS 1YR ANN)","Plan A (CSP COM BAS 1YR ANN)","Plan A (CSP COM BAS 1YR ANN)"], 'Resources': ["Resource A (CSP COM BAS 1YR ANN)","Resource B (CSP COM BAS 1YR ANN)","Resource C (CSP COM BAS 6YR ANN)"]} df = pd.DataFrame(data) print(df) # 错误代码:re.findall无法直接处理Series,且仅取第一行结果,列名还写错了 df[~(name_re.findall(df['ServicePlan'].astype(str))[0]['termduration']).ne(name_re.findall(df['Resource'].astype(str))[0]['termduration'])] print(df)
错误原因
re.findall()是针对单个字符串的方法,直接传入Pandas Series会导致类型不兼容,无法逐行处理。- 代码中用
[0]只提取了第一行的匹配结果,无法实现全表逐行对比。 - 列名写错:
df['Resource']应该是df['Resources']。
正确解决方案
使用Pandas的str.extract()方法,它可以直接对Series进行正则提取,返回包含捕获组的DataFrame,方便后续逐行对比。
完整代码
import pandas as pd import re # 正则表达式(修正末尾转义,确保匹配括号闭合逻辑) e_name = r'(?P<name>.*)\((?P<product>[A-Z]{3})\s(?P<type>[A-Z]{3})\s?(?P<baseattach>BAS|ADD|ATT|SWS)?\s?(?P<telco_overusage>OVG)?\s?(?P<termduration>[A-Z0-9]{3})?\s?(?P<billing>[A-Z0-9]{3})\)' data = {'ServicePlan': ["Plan A (CSP COM BAS 1YR ANN)","Plan A (CSP COM BAS 1YR ANN)","Plan A (CSP COM BAS 1YR ANN)"], 'Resources': ["Resource A (CSP COM BAS 1YR ANN)","Resource B (CSP COM BAS 1YR ANN)","Resource C (CSP COM BAS 6YR ANN)"]} df = pd.DataFrame(data) # 提取两列的termduration到临时列 df['sp_term'] = df['ServicePlan'].str.extract(e_name)['termduration'] df['res_term'] = df['Resources'].str.extract(e_name)['termduration'] # 过滤出两个termduration相等的行,同时删除临时列 filtered_df = df[df['sp_term'] == df['res_term']].drop(['sp_term', 'res_term'], axis=1) print(filtered_df)
输出结果
ServicePlan Resources 0 Plan A (CSP COM BAS 1YR ANN) Resource A (CSP COM BAS 1YR ANN) 1 Plan A (CSP COM BAS 1YR ANN) Resource B (CSP COM BAS 1YR ANN)
说明
str.extract()会自动遍历Series中的每一行字符串,提取指定的命名捕获组,返回对应结果的Series。- 通过对比两个临时列的取值,精准过滤出匹配的行,最后删除临时列即可得到目标DataFrame。
内容的提问来源于stack exchange,提问作者oj43085
相关产品推荐
相关产品推荐

