Pandas使用findall提取正则匹配结果时如何去除行内重复值
逐行提取正则匹配结果并去重实现
需求说明
从Pandas DataFrame的字符串字段中提取正则匹配结果,逐行去除重复值后拼接为字符串,全局去重方法不适用该逐行处理场景。
复现场景
给定库存DataFrame测试数据:
import pandas as pd import re df_inventory = pd.DataFrame([[1000, 'A widget for PEX0043 and PEX7657 in Dept. X7842', 'DPT7843','Part PEX7657'], [1001, 'A widget for PEX7654 in Depts. X7843, X7842', 'DPT7842','Part PEX7658'], [1002, 'A widget for PEX7655 PEX7657 in Dept. X7844, X7844, X7842', 'DPT7845','Part PEX7659'], [1003, 'A widget for PEX7656 PEX7658 in Dept. X7845, X7851, X7850, X7842', 'DPT7844','Part PEX7660'], [1004, 'A widget for PEX7657 in Dept. X7846', 'DPT7847','Part PEX7661'], [1005, 'A widget for PEX7658 in Dept. X7847, X7842', 'DPT7846','Part PEX7655'], [1006, 'A widget for PEX7659 in Dept. X7848, X7842, X7843', 'DPT7849', 'Part PEX7654'], [1007, 'A widget for PEX7660 in Dept. X7849, X7844', 'DPT7848', 'Part PEX0043'], [1008, 'A widget for PEX7661 in Dept. X7850', 'DPT7851', 'Part PEX7656'], [1009, 'A widget for PEX7662 in Dept. X7851,X7842,X7843,X7843,X7845,X7846,X7847', 'DPT7850', 'Part PEX7660']], columns=['Product ID', 'Description', 'Location','Name'])
初始提取代码如下,直接对匹配结果做拼接,没有逐行去重逻辑:
X_pat = re.compile(r'(?<!PE)(X[0-9]{4})') df_inventory['X Numbers'] = df_inventory['Description'].str.findall(X_pat).str.join(", ")
运行后索引为9的行提取结果存在重复值:
9 1009 A widget for PEX7662 in Dept. X7851,X7842,X784... DPT7850 Part PEX7660 X7851, X7842, X7843, X7843, X7845, X7846, X7847
其中X7843重复出现。
实现方案
可以直接通过lambda函数逐行处理,在匹配完成后先去重再拼接。
写法1:保留匹配结果的原始出现顺序(推荐)
Python 3.7及以上版本字典默认保留插入顺序,用dict.fromkeys()去重不会打乱匹配到的内容先后顺序:
df_inventory['X Numbers'] = df_inventory['Description'].apply( lambda col: ", ".join(dict.fromkeys(X_pat.findall(col))) )
处理后索引9行的结果为X7851, X7842, X7843, X7845, X7846, X7847,重复值已被移除,且顺序和原文出现顺序一致。
写法2:不保留顺序的简化写法
如果不需要保留匹配顺序,可以直接用set去重,代码更简短,但输出的编号顺序随机:
df_inventory['X Numbers'] = df_inventory['Description'].apply( lambda col: ", ".join(set(X_pat.findall(col))) )
内容的提问来源于stack exchange,提问作者EA Bubnoff
相关产品推荐
相关产品推荐

